home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n03.arc / JOURNAL.ASM < prev    next >
Assembly Source File  |  1991-01-17  |  186KB  |  4,836 lines

  1. _TEXT          SEGMENT PUBLIC 'CODE'
  2.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  3.  
  4. ; Fix 3/1/90 for no cursor on in some applications.
  5. ; Fix 3/7/90 for ASCII archive file.
  6. ; Fix 8/29/90 for /A nopopup.
  7.  
  8.                ORG     80H
  9. DTA            LABEL   BYTE
  10.  
  11.                ORG     100H
  12. START:         JMP     INITIALIZE
  13.  
  14. ;              DATA AREA
  15. ;              ---------
  16. CR             EQU     13
  17. LF             EQU     10
  18. FF             EQU     12
  19. CTRL_Z         EQU     26
  20. SPACE          EQU     32
  21. BOX            EQU     254
  22. BELL           EQU     7
  23. TAB            EQU     9
  24. ESC_SCAN       EQU     1
  25. ENTER_SCAN     EQU     1CH
  26. Y_SCAN         EQU     15H
  27. N_SCAN         EQU     31H
  28. F1_SCAN        EQU     3BH
  29. F2_SCAN        EQU     3CH
  30. F3_SCAN        EQU     3DH
  31. F4_SCAN        EQU     3EH
  32. F5_SCAN        EQU     3FH
  33. F6_SCAN        EQU     40H
  34. F7_SCAN        EQU     41H
  35. F8_SCAN        EQU     42H
  36. F9_SCAN        EQU     43H
  37. SHIFT_F7_SCAN  EQU     5AH
  38. KB_FLAG        EQU     17H
  39.  
  40. APP_LEN        EQU     29                      ;Chars per appointment.
  41. APP_HEIGHT     EQU     16                      ;Appointment rows.
  42. NOTE_LEN       EQU     73                      ;Notepad line length.
  43. NOTE_HEIGHT    EQU      3                      ;Notepad rows.
  44. DATE_LEN       EQU     11                         ;Date length in ASCII.
  45. NOTEPAD_LEN    EQU     (81 - 4) + 81 + (81 - 4)   ;Total notepad size.
  46.  
  47. DATA_RECORD    STRUC
  48. DATE_BINARY    DW      2 DUP (?)
  49. DATE_ASCII     DB      DATE_LEN DUP (?)
  50. DATA_TEXT      DB      (APP_HEIGHT * APP_LEN * 2) DUP (?)
  51. NOTEPAD_TEXT   DB      NOTEPAD_LEN DUP (?)
  52. DATA_RECORD    ENDS
  53.  
  54. BUFFER         DB      ((82 * 25) + 2 - ($ - OFFSET DTA)) DUP (?)
  55.  
  56. SIGNATURE      DB      SPACE,CR,CR,LF
  57. COPYRIGHT      DB      "JOURNAL 1.0 (c) 1990 Ziff Communications Co.",CR,LF
  58. PROGRAMMER     DB      "PC Magazine ",BOX," Michael J. Mefford",CR,LF,LF,"$"
  59.                DB      CTRL_Z
  60.  
  61. COLOR_ATTRIBS  STRUC
  62. B              DB     017H                     ;White on blue.
  63. H              DB     071H                     ;Blue on white.
  64. Y              DB     01EH                     ;Yellow on blue.
  65. C              DB     03BH                     ;Bright cyan on cyan.
  66. A              DB     01BH                     ;Bright cyan on blue.
  67. P              DB     07EH                     ;Yellow on white.
  68. COLOR_ATTRIBS  ENDS
  69.  
  70. COLOR          COLOR_ATTRIBS  <>
  71.  
  72. COLOR_ATTR     COLOR_ATTRIBS  <>
  73. MONO_ATTR      COLOR_ATTRIBS  <07H, 70H, 70H, 70H, 07H, 07H>
  74.  
  75. MONO_FLAG      DB      0                       ; =1 if forced Black and white.
  76. NOTE           DW      1046                    ;C note
  77.  
  78. DOS_SEGMENT    DW      ?                    ;Segment of internal DOS flags.
  79. INDOS_OFFSET   DW      ?                    ;Offset of INDOS flag.
  80. ERRFLAG_OFFSET DW      ?                    ;Offset of critical error flag.
  81. PROGRAM_STATUS DB      0                    ;Popup status; non-zero=popped up.
  82.  
  83. BUSY_FLAGS     LABEL   WORD
  84. FLAG_10h       DB      0                    ;Status of interrupt 10h.
  85. FLAG_13h       DB      0                    ;Status of interrupt 13h.
  86. BACK_FLAGS     LABEL   WORD
  87. FLAG_8h        DB      0                    ;Status of interrupt 8h.
  88. FLAG_28h       DB      0                    ;Status of interrupt 28h.
  89.  
  90. REQUEST_FLAG   DB      0                    ;Status of processing request.
  91. SS_REGISTER    DW      ?                    ;SS register storage.
  92. SP_REGISTER    DW      ?                    ;SP register storage.
  93. OLDPSP         DW      ?                    ;PSP segment storage.
  94.  
  95. BIOS_ACTIVE_PAGE       EQU     62H
  96. ACTIVE_PAGE    DB      ?
  97. ADDR_6845      DW      ?
  98. BIOS_CRT_MODE          EQU     49H
  99. CRT_MODE       DB      ?
  100. CRT_COLS       DW      ?
  101. CRT_LEN        DW      ?
  102. CRT_START      DW      ?
  103. CRT_DATA_LENGTH        EQU     $ - CRT_MODE
  104.  
  105. CRT_WIDTH      DW      ?                    ;Width in bytes of CRT.
  106. CRT_ROWS       DB      ?
  107. VIDEO_SEG      DW      ?
  108. STATUS_REG     DW      ?
  109. CURSOR_MODE    DW      ?                    ;Cursor shape.
  110. CURSOR_POS     DW      ?                    ;Cursor position.
  111. CURSOR_ADDR    DW      ?                    ;Cursor CRTC address.
  112. SCH_CURSOR     DW      ?
  113.  
  114. DOS_VERSION    DW      ?
  115. TSR_SEGMENT    DW      ?
  116.  
  117. OLD8           DW      ?,?                     ;Old interrupt addresses.
  118. OLD9           DW      ?,?
  119. OLD10          DW      ?,?
  120. OLD13          DW      ?,?
  121. OLD28          DW      ?,?
  122.  
  123. OLD1B          DW      ?,?
  124. OLD23          DW      ?,?
  125. OLD24          DW      ?,?
  126. OLD_DTA        DW      ?,?
  127. BREAK          DB      ?                       ;Ctrl break state.
  128.  
  129. CLOCK          DB      "xx:xxxm",0
  130.  
  131. STATE          DW      CALENDAR                ;Pop up screen.
  132. EXIT_FLAG      DB      0                       ; =1 if Hotkey pressed.
  133.  
  134. CTRL_STATE     EQU     4
  135. ALT_STATE      EQU     8
  136.  
  137. COMBO          DB      "J"
  138. HOT_KEY_SCAN   DB      24H                     ;"J"
  139. HOT_SHIFT_KEY  DB      ALT_STATE
  140.  
  141. MODIFY_FLAG    DB      0                       ; =1 if changes made in apps.
  142.  
  143. PORT_A         EQU     60H
  144. PORT_B         EQU     61H
  145. COMMAND_PORT   EQU     20H
  146. EOI            EQU     20H
  147.  
  148. MATCHING       STRUC
  149. RESERVED       DB      21 DUP (?)
  150. ATTRIBUTE      DB              ?
  151. FILE_TIME      DW              ?
  152. FILE_DATE      DW              ?
  153. SIZE_LOW       DW              ?
  154. SIZE_HIGH      DW              ?
  155. FILE_NAME      DB      13 DUP (?)
  156. MATCHING       ENDS
  157.  
  158. ;---------------------------------------------------------------------------;
  159. ; Code Format: 0 = compressed string; followed by string length and char.   ;
  160. ;              1 = display drop shade char.                                 ;
  161. ;              2 = color follows.                                           ;
  162. ;              3 = string end; if followed by -1 then menu end.             ;
  163. ;              4 = drop shade string end followed by string length.         ;
  164. ;              5 = insert date                                              ;
  165. ;              6 = insert appointment blocks                                ;
  166. ;              7 = skip count / 2 follows.                                  ;
  167. ;---------------------------------------------------------------------------;
  168. CAL_MENU       LABEL   BYTE
  169. DB 2,B
  170. DB "          F3 Today  F7 Journal  ─┘= Appointment        PgUp/Dn=Month  Esc=Exit ",3
  171. DB " ┌─────────────────────────────────────────────────┬──────────────────────────┐ ",3
  172. DB " │     ",2,Y,"Calendar",2,B," ■ PC Magazine ■ Michael J. Mefford │ ",2,Y,SPACE
  173. CAL_DATE       LABEL   BYTE
  174. DB                                                       "                ",7,14,2,B," │ ",3
  175. DB " ╞══════════╤══════════╤══════════╤══════════╤═════╧════╤══════════╤══════════╡ ",3
  176. DB " │   "
  177. DAYS           LABEL   BYTE
  178. DB      "Sun    │   Mon    │   Tue    │   Wed    │   Thu    │   Fri    │   Sat    │ ",3
  179. DB " ├──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤ ",3,-1
  180.  
  181. CAL_DUP        LABEL   BYTE
  182. DB " ├──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┼──┴┴┴┴┴┴┴┴┤ ",3
  183. CAL_MIDDLE     LABEL   BYTE
  184. DB " │",7 DUP (5,6,"┤"),SPACE,3
  185. DB " │",7 DUP (SPACE,SPACE,6,"┤"),SPACE,3,-1
  186.  
  187. DB " └──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┴──┴┴┴┴┴┴┴┴┘ ",3
  188. DB " Appointment block 1 hour periods; 6:00am - 1:30 1st row; 2:00pm - 9:30 2nd row ",3,-1
  189.  
  190.  
  191. APPOINTMENT_BLOCKS     LABEL BYTE              ;Storage for small block chars.
  192. BLOCK_COUNT    EQU     31 * 16
  193. DB          BLOCK_COUNT DUP (SPACE)
  194.  
  195. APP_MENU       LABEL   BYTE
  196. DB 2,B
  197. DB " F2 Save  F3 Today  F4 Purge  F5 Print  F6 Clear Line  F7 Calendar  PgUp/Dn=Day ",3
  198. DB " ┌┬────────────────────────────────────────────────┬──────────────────────────┐ ",3
  199. DB " ╞╡ ",2,Y,"Appointment",2,B," ■ PC Magazine ■ Michael J. Mefford │ ",2,Y,SPACE
  200. APP_DATE       LABEL   BYTE
  201. DB                                                       "                ",7,14,2,B," │ ",3
  202. DB " ╞╪════════════════════════════════════════════════╧══════════════════════════╡ ",3
  203. APP_START      LABEL   BYTE
  204. APP_COL_SPACE    EQU   7                       ;Distance from end left to start right.
  205. APP_ROW_SPACE    EQU   16                      ;Distance from end right to start left.
  206. APP_LEFT_START   EQU   $ + 12
  207. APP_RIGHT_START  EQU   APP_LEFT_START + APP_LEN + APP_COL_SPACE
  208. APP_NOTE_SPACE   EQU   8
  209. DB " ╞╡  6:00am                                2:00                               │ ",3
  210. DB " ╞╡  6:30                                  2:30                               │ ",3
  211. DB " ╞╡  7:00                                  3:00                               │ ",3
  212. DB " ╞╡  7:30                                  3:30                               │ ",3
  213. DB " ╞╡  8:00                                  4:00                               │ ",3
  214. DB " ╞╡  8:30                                  4:30                               │ ",3
  215. DB " ╞╡  9:00                                  5:00                               │ ",3
  216. DB " ╞╡  9:30                                  5:30                               │ ",3
  217. DB " ╞╡ 10:00                                  6:00                               │ ",3
  218. DB " ╞╡ 10:30                                  6:30                               │ ",3
  219. DB " ╞╡ 11:00                                  7:00                               │ ",3
  220. DB " ╞╡ 11:30                                  7:30                               │ ",3
  221. DB " ╞╡ 12:00pm                                8:00                               │ ",3
  222. DB " ╞╡ 12:30                                  8:30                               │ ",3
  223. DB " ╞╡  1:00                                  9:00                               │ ",3
  224. DB " ╞╡  1:30                                  9:30                               │ ",3
  225. DB " ╞╪══════════════════════════════[Mini Notepad]═══════════════════════════════╡ ",3
  226. DB " ╞╡ "
  227. NOTEPAD        LABEL   BYTE
  228. DB     "                                                                          │ ",3
  229. DB " ╞╡                                                                           │ ",3
  230. DB " ╞╡                                                                           │ ",3
  231. APP            LABEL   BYTE
  232. DB " └┴───────────────────────────────────────────────────────────────────────────┘ ",3,-1
  233. APP_WIDTH      EQU     $ - APP - 1
  234.  
  235.  
  236. SCH_REPORT_MSG DB 2,H,"╔",   0,27,"═",            "╗",3
  237.                DB     "║ F7 Schedule Report - LPT1 ║",1
  238.                DB     "║ F8 Schedule Report - LPT2 ║",1
  239.                DB     "║ F9 Schedule Report - File ║",1
  240.                DB     "║    Esc to Cancel          ║",1
  241.                DB     "╚",   0,27,"═",            "╝",1,4,29
  242.  
  243. ;----------------------------------------------;
  244. DISK_FULL_MSG  DB 2,H,"╔",      0,25,"═",       "╗",3
  245.                DB     "║  Not enough disk space. ║",1
  246.                DB     "║     Press any key.      ║",1
  247.                DB     "╚",      0,25,"═",       "╝",1,4,27
  248.  
  249. PERMANENT_MSG  DB 2,H,"╔",      0,25,"═",       "╗",3
  250.                DB     "║ Do you wish to save the ║",1
  251.                DB     "║ changes to disk?  Y/N   ║",1
  252.                DB     "╚",      0,25,"═",       "╝",1,4,27
  253.  
  254. PERMANENT_FAIL DB 2,H,"╔",      0,25,"═",       "╗",3
  255.                DB     "║  Update failed.  Press  ║",1
  256.                DB     "║  any key to continue.   ║",1
  257.                DB     "╚",      0,25,"═",       "╝",1,4,27
  258.  
  259. SAVED_MSG      DB 2,H,"╔",0,9, "═╗",3
  260.                DB     "║  Saved  ║",1
  261.                DB     "╚",0,9, "═╝",1,4,11
  262.  
  263. DISK LABEL BYTE
  264. DB 2,H,"╔",      0,27,"═",         "╗",3
  265. DB     "║",      0,27,SPACE,       "║",1
  266. DISK_NAME     LABEL  BYTE
  267. DB     "║   Error reading drive X   ║",1,3,-1
  268.  
  269. ERR_BOT LABEL BYTE
  270. DB     "║   (R)etry or (A)bort ?    ║",1
  271. DB     "║",      0,27,SPACE,       "║",1
  272. DB     "╚",      0,27,"═",         "╝",1,4,ERR_WIDTH
  273.  
  274. PRN LABEL BYTE
  275. DB 2,H,"╔",      0,27,"═",           "╗",3
  276. DB     "║",      0,27,SPACE,         "║",1
  277. DB     "║",0,7," Printer Error",0,7," ║",1,3,-1
  278.  
  279. ERR_WIDTH      EQU     29
  280. ERR_HEIGHT     EQU     6
  281. ERR_ROW        EQU     ((25 - ERR_HEIGHT) / 2) + 3
  282. ERR_COL        EQU     ((80 - ERR_WIDTH) / 2)
  283.  
  284.  
  285. PURGE_MSG      DB 2,H,"╔",0,41,               "═",              "╗",3
  286.                DB     "║ Appointment Purge Date: ",2,P
  287. PUR_DATE       DB                               "                ",2,H,"║",1
  288.                DB     "║   PgUp/Dn to change Date; F3 = Today    ║",1
  289.                DB     "║   F7 Purge up to and including Date     ║",1
  290.                DB     "║   F8 Purge Date Only     Esc to Cancel  ║",1
  291.                DB     "╚",0,41,               "═",              "╝",1,4,43
  292.  
  293. ARCHIVE_MSG    DB 2,H,"╔",0,17,        "═╗",3
  294.                DB     "║  Archive  Y/N?  ║",1
  295.                DB     "╚",0,17,        "═╝",1,4,19
  296.  
  297. PURGING_MSG    DB 2,H,"╔",0,11,  "═╗",3
  298.                DB     "║  Purging  ║",1
  299.                DB     "╚",0,11,  "═╝",1,4,13
  300.  
  301. ;------------------------------------------------------------------------------
  302. ;Execution comes here thru interrupt 9 every time a key is pressed or released.
  303. ;------------------------------------------------------------------------------
  304. KEYBOARD       PROC    NEAR
  305.                PUSH    AX
  306.                PUSH    DS
  307.  
  308.                MOV     AX,40H
  309.                MOV     DS,AX
  310.                MOV     AH,DS:[KB_FLAG]         ;Get keyboard shift status
  311.                PUSH    CS
  312.                POP     DS
  313. KEYSTROKE:     IN      AL,PORT_A
  314.                TEST    AH,HOT_SHIFT_KEY        ;Our shift key?
  315.                JZ      KB_EXIT                 ;No, then exit
  316.                CMP     AL,HOT_KEY_SCAN         ;Our hotkey?
  317.                JNZ     KB_EXIT
  318.                CMP     PROGRAM_STATUS,0        ;Popup routine already active?
  319.                JNZ     KB_EXIT                 ;Yes, then ignore keypress
  320.  
  321.                IN      AL,PORT_B               ;Retrieve Port B.
  322.                OR      AL,80H                  ;Turn bit 7 on to reset
  323.                JMP     $ + 2                   ;I/O delay.
  324.                OUT     PORT_B,AL               ;Reset KBD.
  325.                AND     AL,NOT 80H              ;Turn bit 7 back off.
  326.                JMP     $ + 2                   ;I/O delay.
  327.                OUT     PORT_B,AL               ;Restore port.
  328.  
  329.                CLI                             ;Interrupts off.
  330.                MOV     AL,EOI                  ;Send End Of Interrupt
  331.                OUT     COMMAND_PORT,AL         ; to 8259A PIC.
  332.  
  333.                MOV     REQUEST_FLAG,18         ;Try to popup for one second.
  334.                POP     DS
  335.                POP     AX
  336.                IRET
  337.  
  338. KB_EXIT:       POP     DS
  339.                POP     AX
  340.                JMP     DWORD PTR CS:OLD9       ;Call keyboard handling routine.
  341. KEYBOARD       ENDP
  342.  
  343. ;------------------------------------------------------------------------------
  344. ;Interrupt 8 handling routine.
  345. ;------------------------------------------------------------------------------
  346. LAST_MIN       DB      ?                       ;Last minute.
  347. BELL_FLAG      DB      0                       ; =1 if chiming.
  348. BELL_CNT       DB      ?                       ; no. of chimes.
  349. POPUP_FLAG     DB      0                       ; =1 if alarm or day rollover.
  350. NOPOPUP_FLAG   DB      0                       ; =1 if ignore POPUP_FLAG.
  351. NOBELL_FLAG    DB      0                       ; =1 if ignore chime.
  352. NOMIDNIGHT_FLAG DB     0                       ; =1 if ignore rollover pop up.
  353. ALARM_FLAG     DB      0                       ; =1 only on alarm to avoid homing cursor.
  354. REREAD_FLAG    DB      0                       ; =1 if forced reread of disk.
  355.  
  356. TIMER          PROC    NEAR
  357.                CLI
  358.                PUSHF
  359.                CALL    CS:DWORD PTR OLD8
  360.                PUSH    AX
  361.                PUSH    BX
  362.                PUSH    CX
  363.                PUSH    DX
  364.                PUSH    SI
  365.                PUSH    DI
  366.                PUSH    DS
  367.                PUSH    ES
  368.                PUSH    BP
  369.                CLD
  370.                MOV     BX,CS
  371.                MOV     DS,BX
  372.                CMP     PROGRAM_STATUS,0        ;Already popped up?
  373.                JNZ     CK_TIME
  374.                CMP     FLAG_8h,0
  375.                JNZ     CK_TIME
  376.                CMP     POPUP_FLAG,1            ;Alarm or rollover popup?
  377.                JNZ     CK_REQ_FLAG
  378.                MOV     REQUEST_FLAG,18         ;Request to popup for 1 sec.
  379. CK_REQ_FLAG:   CMP     REQUEST_FLAG,0
  380.                JZ      CK_TIME
  381.  
  382. CK_TSRSTATE:   INC     FLAG_8h
  383.                STI
  384.                CALL    TSR_STATE               ;Save to enter Dos? 
  385.                JC      DECTIME
  386.                CALL    MAIN
  387.                JMP     SHORT TIMER_DONE
  388.  
  389.  
  390. DECTIME:       CMP     REQUEST_FLAG,0
  391.                JZ      TIMER_DONE
  392.                DEC     REQUEST_FLAG
  393.                JZ      TIMER_BEEP
  394.                CMP     REQUEST_FLAG,9          ;Beep twice, once every 1/2 sec.
  395.                JNZ     TIMER_DONE
  396. TIMER_BEEP:    CALL    BEEP
  397. TIMER_DONE:    CLI
  398.                DEC     FLAG_8h
  399.  
  400. TIMER_END:     POP     BP
  401.                POP     ES
  402.                POP     DS
  403.                POP     DI
  404.                POP     SI
  405.                POP     DX
  406.                POP     CX
  407.                POP     BX
  408.                POP     AX
  409.                IRET
  410.  
  411. ;----------------------------------------------;
  412. CK_TIME:       STI
  413.                MOV     AX,40H
  414.                MOV     ES,AX
  415.                MOV     CX,ES:[6CH]             ;TIMER_LOW
  416.                MOV     AX,ES:[6EH]             ;TIMER_HIGH
  417.                MOV     BP,AX                   ;Save hour.
  418.                PUSH    CS
  419.                POP     ES
  420.  
  421.                MOV     BL,"a"                  ;Convert time to 12 hour version.
  422.                CMP     AX,24
  423.                JZ      GOT_MUNDI
  424.                CMP     AX,11
  425.                JBE     GOT_MUNDI
  426.                MOV     BL,"p"
  427. GOT_MUNDI:     OR      AX,AX
  428.                JNZ     CK_NOON
  429.                MOV     AX,12
  430. CK_NOON:       CMP     AX,12
  431.                JBE     GOT_HOUR
  432.                SUB     AX,12
  433. GOT_HOUR:      MOV     DI,OFFSET CLOCK
  434.                XOR     SI,SI                   ;Suppress leading zero.
  435.                CALL    STORE_NUMBER
  436.  
  437.                MOV     AX,CX
  438.                XOR     DX,DX
  439.                MOV     CX,1093                 ;Convert ticks to minutes.
  440.                DIV     CX
  441.                INC     SI                      ;Store leading zero.
  442.                MOV     CL,CLOCK + 4            ;Retrieve current minute.
  443.                MOV     LAST_MIN,CL             ;Store new current minute.
  444.                CALL    STORE_NUMBER
  445.                MOV     [DI - 1],BL             ;Store am or pm.
  446.  
  447. CK_DISP_CLOCK: CMP     PROGRAM_STATUS,2        ;If not popped up, no
  448.                JNZ     CK_BELL                 ; clock display.
  449. DISP_TIME:     MOV     AX,2
  450.                CALL    CALC_ADDR
  451.                ADD     DI,70 * 2
  452.                MOV     BH,COLOR.Y
  453.                MOV     SI,OFFSET CLOCK
  454.                MOV     DX,STATUS_REG
  455.                PUSH    ES
  456.                MOV     ES,VIDEO_SEG
  457.                JMP     SHORT WRITE_CLOCK
  458. NEXT_CLOCK:    CALL    WRITE_SCREEN            ;Display clock.
  459. WRITE_CLOCK:   LODSB
  460.                OR      AL,AL
  461.                JNZ     NEXT_CLOCK
  462.                POP     ES
  463.  
  464. CK_BELL:       CMP     BELL_FLAG,0             ;Is alarm chiming?
  465.                JZ      CK_MINUTE
  466.                JMP     DO_BELL
  467.  
  468. CK_MINUTE:     MOV     AX,WORD PTR CLOCK + 3   ;Retrieve current minute.
  469.                CMP     AH,LAST_MIN             ;Same as last minute?
  470.                JNZ     CK_ALARM
  471.                JMP     TIMER_END               ;If yes, done.
  472. CK_ALARM:      CMP     AX,"1" SHL 8 + "0"      ;Else, is it :01?
  473.                JZ      CK_ROLLOVER             ;If yes, check if 12:01.
  474.                SUB     AX,"0" SHL 8 + "0"      ;Else, adjust to binary.
  475.                OR      AH,AH                   ;Minute zero?
  476.                JZ      ADJUST_TIME
  477. TIMER_LILLY:   JMP     TIMER_END               ;If no, done.
  478.  
  479. CK_ROLLOVER:   OR      BP,BP                   ;Is it 12:01am?
  480.                JNZ     TIMER_LILLY             ;If no, done.
  481.                MOV     REREAD_FLAG,1           ;Else, reread disk alarms.
  482.                CMP     PROGRAM_STATUS,0        ;Are we popped up?
  483.                JNZ     FIX_DATE                ;If yes, fix date now.
  484.                CMP     NOMIDNIGHT_FLAG,1       ;Else, ignore rollover?
  485.                JZ      TIMER_LILLY             ;If yes, done.
  486.                MOV     POPUP_FLAG,1            ;Else, popup request.
  487.                JMP     TIMER_LILLY
  488. FIX_DATE:      CALL    UPDATE_DATE             ;Fix date.
  489.                JMP     TIMER_LILLY
  490.  
  491. ADJUST_TIME:   SUB     BP,6                    ; 6:00am
  492.                JS      EXIT_TIMER
  493.                CMP     BP,15                   ; 9:00pm
  494.                JA      EXIT_TIMER
  495.                OR      AL,AL                   ; xx:00
  496.                JZ      CK_MATCH
  497.                CMP     AL,3                    ; xx:30
  498.                JNZ     EXIT_TIMER
  499.                AND     AL,1                    ;Convert to index.
  500.  
  501. CK_MATCH:      CMP     PROGRAM_STATUS,0        ;Popped up?
  502.                JNZ     EXIT_TIMER              ;If yes, no alarms.
  503.                CBW
  504.                SHL     BP,1                    ;Hour * 2.
  505.                ADD     AX,BP                   ; + half hour index.
  506.                MOV     DI,AX
  507.                CMP     BYTE PTR ALARMS[DI],1   ;Appointment?
  508.                JNZ     EXIT_TIMER              ;If no, done.
  509.  
  510.                CMP     NOPOPUP_FLAG,1          ;No pop up request by user?
  511.                JZ      CK_BELL_FLAG            ;If yes, check chime.
  512.                MOV     ALARM_FLAG,1            ;Else, flag no cursor change
  513.                MOV     APP_INDEX,APP_LEFT      ; when disk reread to today.
  514.                MOV     DX,DI
  515.                XCHG    DH,DL                   ;Place cursor on appointment.
  516.                MOV     DL,12
  517.                CMP     DH,16
  518.                JB      MOVE_CURSOR
  519.                MOV     APP_INDEX,APP_RIGHT
  520.                SUB     DH,16
  521.                MOV     DL,48
  522. MOVE_CURSOR:   ADD     DH,4                    ;Starts on fourth row.
  523.                MOV     APP_CURSOR,DX
  524.  
  525.                MOV     POPUP_FLAG,1            ;If yes, just pop up.
  526.  
  527. CK_BELL_FLAG:  CMP     NOBELL_FLAG,1           ;No chime request by user?
  528.                JZ      EXIT_TIMER
  529.  
  530. START_BELL:    MOV     BELL_CNT,14 * 2         ;14 chirps for chime.
  531.                MOV     BELL_FLAG,1
  532.                CALL    SETUP_BELL
  533. DO_BELL:       CALL    FLIP_BELL
  534.  
  535. EXIT_TIMER:    JMP     TIMER_END
  536.  
  537. TIMER          ENDP
  538.  
  539. ;-------------------------------------------------------------
  540. ; INPUT: SI = 0 not to suppress leading zero; SI = 1 suppress.
  541. STORE_NUMBER:  MOV     BH,10
  542.                DIV     BH
  543.                ADD     AX,"00"
  544.                OR      SI,SI
  545.                JNZ     STORE_IT
  546.                CMP     AL,"0"
  547.                JNZ     STORE_IT
  548.                MOV     AL,SPACE
  549. STORE_IT:      STOSB
  550.                XCHG    AH,AL
  551.                STOSB
  552.                INC     DI
  553.                RET
  554.  
  555. ;------------------------------------------------------------------------------
  556. ;Interrupt 10h handling routine.
  557. ;------------------------------------------------------------------------------
  558. VIDEO          PROC    NEAR
  559.                INC     CS:FLAG_10H             ;No popup while in a int 10h.
  560.                PUSHF
  561.                CLI
  562.                CALL    DWORD PTR CS:OLD10
  563.                DEC     CS:FLAG_10H
  564.                IRET
  565. VIDEO          ENDP
  566.  
  567. ;------------------------------------------------------------------------------
  568. ;Interrupt 13h handling routine.
  569. ;------------------------------------------------------------------------------
  570. BDISK          PROC    FAR
  571.                PUSHF
  572.                INC     CS:FLAG_13H             ;No popup while disk activity.
  573.                CLI
  574.                CALL    DWORD PTR CS:OLD13      ;Call BIOS routine
  575.                PUSHF
  576.                DEC     CS:FLAG_13H
  577.                POPF
  578.                STI
  579.                RET     2                       ;Preserve flags.
  580. BDISK          ENDP
  581.  
  582. ;------------------------------------------------------------------------------
  583. ;Interrupt 28h handling routine.
  584. ;------------------------------------------------------------------------------
  585. BACKPROC       PROC    NEAR
  586.                PUSH    AX
  587.                PUSH    DS
  588.                MOV     AX,CS
  589.                MOV     DS,AX
  590.                CLI
  591.                PUSHF
  592.                CALL    DWORD PTR OLD28
  593.                CMP     REQUEST_FLAG,0          ;Popup requested?
  594.                JZ      BP_EXIT
  595.                CMP     BACK_FLAGS,0            ;Save to popup?
  596.                JNZ     BP_EXIT
  597.                CMP     PROGRAM_STATUS,0        ;Already popped up?
  598.                JNZ     BP_EXIT
  599.  
  600.                INC     FLAG_28h
  601.                STI
  602.                CLD
  603.                PUSH    BX
  604.                PUSH    CX
  605.                PUSH    DX
  606.                PUSH    SI
  607.                PUSH    DI
  608.                PUSH    ES
  609.                PUSH    BP
  610.                CALL    TSR_STATE               ;Save to enter Dos?
  611.                JC      BP_DONE
  612.                CALL    MAIN
  613. BP_DONE:       POP     BP
  614.                POP     ES
  615.                POP     DI
  616.                POP     SI
  617.                POP     DX
  618.                POP     CX
  619.                POP     BX
  620.                DEC     FLAG_28h
  621. BP_EXIT:       POP     DS
  622.                POP     AX
  623.                IRET
  624. BACKPROC       ENDP
  625.  
  626. ;----------------------------------------------;
  627. TSR_STATE:     PUSH    AX
  628.                CMP     BUSY_FLAGS,0
  629.                JNZ     TSR_BUSY
  630.  
  631.                MOV     ES,DOS_SEGMENT          ;Check INDOS flag.
  632.                MOV     BX,INDOS_OFFSET
  633.                MOV     AL,ES:[BX]
  634.                MOV     BX,ERRFLAG_OFFSET       ;Check critical error flag.
  635.                MOV     AH,ES:[BX]
  636.                XOR     BX,BX
  637.                CMP     BL,FLAG_28h
  638.                RCL     BL,1
  639.                CMP     BX,AX
  640.                JC      TSR_END
  641.  
  642. ; Checking for hardware interrupts will avoid lost of chars in Async.
  643.                MOV     AX,00001011B
  644.                OUT     20H,AL
  645.                JMP     $ + 2
  646.                IN      AL,20H
  647.                CMP     AH,AL
  648.                JC      TSR_END
  649.  
  650. TSR_OK:        CLC
  651.                JMP     SHORT TSR_END
  652.  
  653. TSR_BUSY:      STC
  654. TSR_END:       POP     AX
  655.                RET
  656.  
  657. ;-----------------------------------------------;
  658. ; This is the new Critical Error interrupt 24h. ;
  659. ;-----------------------------------------------;
  660. ERR_CURSOR     DW      ?                       ; Current cursor position.
  661. ERR_CORNER     DW      ?                       ; Address for error message.
  662. ABORT          DB      0                       ; =1 if user chose to abort.
  663.  
  664. IOERR:         STI
  665.                PUSH    BX
  666.                PUSH    CX
  667.                PUSH    DX
  668.                PUSH    SI
  669.                PUSH    DI
  670.                PUSH    BP
  671.                PUSH    DS
  672.                PUSH    ES
  673.  
  674.                MOV     BX,CS
  675.                MOV     DS,BX
  676.                MOV     ES,BX
  677.                CLD
  678.                ADD     AL,"A"
  679.                MOV     DISK_NAME + 24,AL       ;Convert and save drive letter.
  680.  
  681.                MOV     SI,OFFSET DISK          ;Disk or printer critical error?
  682.                TEST    AH,10000000B
  683.                JZ      SAVE_IT
  684.                MOV     SI,OFFSET PRN
  685.  
  686. SAVE_IT:       PUSH    SI                      ;Save screen contents we are
  687.                MOV     BH,ACTIVE_PAGE          ; going to write over.
  688.                MOV     AH,3
  689.                INT     10H
  690.                MOV     ERR_CURSOR,DX           ;Save cursor position and
  691.                CALL    HIDE_CURSOR             ; hide it off screen.
  692.  
  693.                MOV     AX,ERR_ROW              ;Popup error message.
  694.                CALL    CALC_ADDR
  695.                ADD     AX,ERR_COL * 2
  696.                MOV     ERR_CORNER,AX
  697.  
  698.                MOV     SI,AX
  699.                MOV     DI,OFFSET ERR_SAVE
  700.                MOV     CX,ERR_HEIGHT + 1
  701.                MOV     BP,ERR_WIDTH + 2
  702.                CALL    DO_SAVE
  703.  
  704.                POP     SI
  705.                MOV     DI,ERR_CORNER
  706.                CALL    POP_WINDOW
  707.                MOV     DI,ERR_CORNER
  708.                MOV     AX,CRT_WIDTH
  709.                ADD     DI,AX
  710.                ADD     DI,AX
  711.                ADD     DI,AX
  712.                MOV     SI,OFFSET ERR_BOT
  713.                CALL    POP_WINDOW
  714.                CALL    BEEP
  715.  
  716. WAIT_KEY:      XOR     AH,AH                   ;Get a user response.
  717.                INT     16H
  718.                MOV     AL,1
  719.                CMP     AH,13H                  ;Was it scan code for "R"?
  720.                JZ      ERR_END
  721.                CMP     AH,1EH                  ;Was it "A"?
  722.                JNZ     WAIT_KEY                ;If no, wait until valid
  723.                MOV     ABORT,1                 ; response.
  724.                MOV     AL,3                    ;Fail.
  725.                CMP     DOS_VERSION,300H        ;DOS 2 can't handle fail request.
  726.                JAE     ERR_END
  727.                XOR     AL,AL
  728.  
  729. ERR_END:       PUSH    AX
  730.                MOV     DI,ERR_CORNER           ;Restore screen.
  731.                MOV     SI,OFFSET ERR_SAVE
  732.                MOV     CX,ERR_HEIGHT + 1
  733.                MOV     BP,ERR_WIDTH + 2
  734.                CALL    DO_RESTORE
  735.                MOV     DX,ERR_CURSOR
  736.                CALL    SET_CURSOR              ;Restore cursor position.
  737.                POP     AX
  738.  
  739.                POP     ES                      ;Restore registers.
  740.                POP     DS
  741.                POP     BP
  742.                POP     DI
  743.                POP     SI
  744.                POP     DX
  745.                POP     CX
  746.                POP     BX
  747. IOEXIT:        IRET
  748.  
  749. ;------------------------------------------------------------------------------
  750. ;MAIN is the routine called to pop up the window.
  751. ;------------------------------------------------------------------------------
  752. MAIN           PROC    NEAR
  753.                MOV     PROGRAM_STATUS,1        ;Flag in process of popping up.
  754.                MOV     REQUEST_FLAG,0          ;Reset request counter.
  755.                MOV     SS_REGISTER,SS          ;Setup own stack.
  756.                MOV     SP_REGISTER,SP
  757.                MOV     AX,CS
  758.                MOV     SS,AX
  759.                MOV     SP,OFFSET OUR_STACK
  760.                STI
  761.                MOV     ES,AX
  762.  
  763.                CALL    GET_BIOS_DATA
  764.                MOV     AL,CRT_MODE             ;Is it video mode BW80, CO80
  765.                CMP     AL,3                    ; or MONO?
  766.                JZ      MAIN1
  767.                CMP     AL,2
  768.                JZ      MAIN1
  769.                CMP     AL,7
  770.                JZ      MAIN1
  771. QUICK_EXIT:    CMP     POPUP_FLAG,1            ;If no, can't popup; beep to tell
  772.                JZ      EXIT                    ; user only if was hotkey popup.
  773.                CALL    BEEP
  774.  
  775. ;----------------------------------------------;
  776. ; MAIN exit.                                   ;
  777. ;----------------------------------------------;
  778. EXIT:          CLI
  779.                MOV     SS,SS_REGISTER          ;Restore stack.
  780.                MOV     SP,SP_REGISTER
  781.                MOV     PROGRAM_STATUS,0
  782.                RET
  783.  
  784. ;----------------------------------------------;
  785. MAIN1:         CMP     CRT_COLS,80             ;At least 80 columns?
  786.                JB      QUICK_EXIT
  787.  
  788. GET_COLORS:    CALL    GET_CUR_ADDR            ;Save cursor address.
  789.                CMP     MONO_FLAG,1             ;Forced Black and white?
  790.                JZ      DO_MONO
  791.                MOV     SI,OFFSET COLOR_ATTR    ;Select color or mono
  792.                CMP     CRT_MODE,3              ; attributes.
  793.                JZ      GOT_ATTR
  794. DO_MONO:       MOV     SI,OFFSET MONO_ATTR
  795. GOT_ATTR:      MOV     DI,OFFSET COLOR
  796.                MOV     CX,SIZE COLOR_ATTRIBS
  797.                REP     MOVSB
  798.  
  799. MAIN5:         MOV     AH,51H
  800.                CALL    INT21_PSP               ;Get PSP.
  801.                MOV     OLDPSP,BX
  802.                PUSH    CS
  803.                POP     BX
  804.                MOV     AH,50H                  ;Set PSP.
  805.                CALL    INT21_PSP
  806.  
  807.                MOV     AH,2FH
  808.                INT     21H
  809.                MOV     OLD_DTA[0],BX           ;Get DTA.
  810.                MOV     OLD_DTA[2],ES
  811.                MOV     DX,OFFSET DTA
  812.                MOV     AH,1AH                  ;Set DTA.
  813.                INT     21H
  814.  
  815.                MOV     AX,3300H                ;Get break.
  816.                INT     21H
  817.                MOV     BREAK,DL
  818.                XOR     DL,DL                   ;Break off.
  819.                MOV     AX,3301H
  820.                INT     21H
  821.  
  822. MAIN6:         PUSH    CS
  823.                POP     ES
  824.                CALL    IOSET                   ;Set up critical error handler.
  825.                CALL    UPDATE_DATE
  826.                CALL    SAVE_SCREEN
  827.                MOV     EXIT_FLAG,0
  828.                CMP     POPUP_FLAG,1            ;Alarm or rollover?
  829.                JNZ     READY
  830.                MOV     POPUP_FLAG,0
  831.                MOV     STATE,OFFSET APPOINTMENT  ;If yes, popup in appointments
  832.                CALL    CTODAY                    ; on today.
  833. READY:         MOV     PROGRAM_STATUS,2          ;Flag so clock displayed.
  834.                MOV     CX,SCH_CURSOR
  835.                MOV     AH,1
  836.                INT     10H
  837.  
  838. ;------------------------------;
  839. ;    M A I N    L O O P        ;
  840. ;------------------------------;
  841. NEXT_STATE:    MOV     REREAD_FLAG,1
  842.  
  843.                CALL    HIDE_CURSOR
  844.                CALL    STATE
  845.                CMP     EXIT_FLAG,1             ;If Esc Calendar or Hotkey, exit.
  846.                JNZ     NEXT_STATE
  847.  
  848. ESCAPE:        MOV     PROGRAM_STATUS,1        ;Disable clock display.
  849.                CALL    RESTORE_SCREEN
  850.  
  851.                MOV     BX,OLDPSP               ;Restore PSP.
  852.                MOV     AH,50H
  853.                CALL    INT21_PSP
  854.  
  855.                PUSH    DS                      ;Restore DTA.
  856.                LDS     DX,DWORD PTR OLD_DTA
  857.                MOV     AH,1AH
  858.                INT     21H
  859.                POP     DS
  860.  
  861.                MOV     DL,BREAK                ;Restore BREAK.
  862.                MOV     AX,3301H
  863.                INT     21H
  864.  
  865.                CALL    IORESET                 ;Restore critical handler.
  866.  
  867.                MOV     BH,ACTIVE_PAGE          ;Restore cursor.
  868.                MOV     DX,CURSOR_POS
  869.                MOV     AH,2
  870.                INT     10H
  871.                MOV     DX,ADDR_6845            ;Recover CRTC base address
  872.                MOV     CX,CURSOR_ADDR
  873.                MOV     AL,14
  874.                OUT     DX,AL
  875.                INC     DX
  876.                MOV     AL,CH
  877.                OUT     DX,AL
  878.                DEC     DX
  879.                MOV     AL,15
  880.                OUT     DX,AL
  881.                INC     DX
  882.                MOV     AL,CL
  883.                OUT     DX,AL
  884.  
  885.                MOV     CX,CURSOR_MODE
  886.                MOV     AH,1
  887.                INT     10H
  888.  
  889.                JMP     EXIT
  890. MAIN           ENDP
  891.  
  892. ;----------------------------------------------;
  893. INT21_PSP:     CMP     DOS_VERSION,30AH        ;PSP call DOS 3 or above.
  894.                JB      INT21_PSP2
  895.                INT     21H
  896.                RET
  897.  
  898. INT21_PSP2:    PUSH    DS                      ;Else, fake via error.
  899.                MOV     DI,ERRFLAG_OFFSET
  900.                MOV     DS,DOS_SEGMENT
  901.                INC     BYTE PTR [DI]
  902.                INT     21H
  903.                DEC     BYTE PTR [DI]
  904.                POP     DS
  905.                RET
  906.  
  907. ;------------------------------------------;
  908. ; OUTPUT: ZF=1 if aborted.  CY=1 if failed ;
  909. ;------------------------------------------;
  910. ZR             EQU     1000000B                ;Bit for zero flag in register.
  911.  
  912. INT21_IO:      INT     21H
  913.                PUSH    AX                      
  914.                LAHF                            ;Save flag's results of DOS call.
  915.                AND     AH,NOT ZR               ;Assume zero flag zero.
  916.                CMP     ABORT,1                 ;Was there an abort from
  917.                JNZ     INT21_IO_END            ; critical error?
  918.                OR      AH,ZR                   ;If yes, turn zero bit on.
  919.                MOV     ABORT,0                 ;Reset abort flag.
  920. INT21_IO_END:  SAHF                            ;Return results in flags reg.
  921.                POP     AX
  922.                RET
  923.  
  924. ;----------------------------------------------;
  925.  
  926. UPDATE_DATE:   MOV     AH,2AH                  ;Get the date from DOS.
  927.                INT     21H
  928.                MOV     YEAR_TODAY,CX
  929.                MOV     DAY_MON_TODAY,DX
  930.                RET
  931.  
  932. ;**********************************************;
  933. ;       F U N C T I O N   C A L L S
  934. ;**********************************************;
  935. MONTHS         DB      "JanFebMarAprMayJunJulAugSepOctNovDec"
  936. NUMDAYS        DB       31,28,31,30,31,30,31,31,30,31,30,31
  937.  
  938. YEAR_CAL       DW      ?                       ;Year displayed.
  939. DAY_MON_CAL    LABEL   WORD
  940. DAY_CAL        DB      ?                       ;Day cursor is on.
  941. MONTH_CAL      DB      ?                       ;Month displayed.
  942.  
  943. YEAR_TODAY     DW      ?                       ;Current year.
  944. DAY_MON_TODAY  LABEL   WORD
  945. DAY_TODAY      DB      ?                       ;Current day.
  946. MONTH_TODAY    DB      ?                       ;Current month.
  947.  
  948. YEAR_CUR       DW      ?                       ;Last year displayed.
  949. DAY_MON_CUR    LABEL   WORD
  950. DAY_CUR        DB      ?                       ;Last day displayed.
  951. MONTH_CUR      DB      -1                      ;Last month displayed.
  952.  
  953. WEEKDAY        DB      ?                       ;Day of week for 1st.
  954. LAST_DAY       DB      ?                       ;Last day of month.
  955. DAY_COUNTER    DB      ?                       ;Day display counter.
  956. BLOCK_COUNTERS LABEL   WORD
  957. BLOCK_COUNTER  DB      ?,?                     ;Block display counters.
  958. BLOCK_ROW      DW      0                       ;Block row index.
  959.  
  960. CTABLE         DB  3DH
  961.                DB  4BH,   4DH,    48H,       50H,       47H,       4FH
  962.                DB  49H,   51H,    84H,       76H,       77H,       75H
  963.                DB  73H,   74H
  964. CTABLE_LEN     EQU     $ - CTABLE
  965.                DW  CTODAY
  966.                DW  CLEFT, CRIGHT, CUP,       CDOWN,     CHOME,     CEND
  967.                DW  CPGUP, CPGDN,  CCTRLPGUP, CCTRLPGDN, CCTRLHOME, CCTRLEND
  968.                DW  CHOME, CEND
  969.  
  970. CALENDAR:      MOV     SI,OFFSET SCH_DAT
  971.                CALL    APPEND
  972.  
  973.                CALL    CK_DATE                 ;See if date changed.
  974.  
  975.                MOV     SI,OFFSET CAL_MENU      ;Pop up calendar screen.
  976.                CALL    POP_MENU
  977.  
  978.                MOV     DAY_COUNTER,0           ;Counters for day and
  979.                MOV     BLOCK_COUNTERS,0        ; cursor display.
  980.                MOV     SI,OFFSET CAL_MIDDLE
  981.                CALL    POP_WINDOW
  982.                MOV     CX,5
  983. NEXT_CALROW:   PUSH    CX
  984.                MOV     SI,OFFSET CAL_DUP
  985.                CALL    POP_WINDOW
  986.                POP     CX
  987.                LOOP    NEXT_CALROW
  988.                INC     SI
  989.                CALL    POP_WINDOW
  990.  
  991.                CALL    GETKEY                  ;Get a keystroke.
  992.                JC      CALENDAR_DONE           ;Exit if Esc or hotkey.
  993.                CMP     AL,ENTER_SCAN           ;If Enter, then go to
  994.                JZ      GOTO_APP                ; appointment screen.
  995.                CMP     AL,31H                  ;If "N" scan code.
  996.                JZ      GOTO_NOTE
  997.  
  998.                CMP     AL,SHIFT_F7_SCAN
  999.                JNZ     CK_CAL_F7
  1000.                MOV     STATE,OFFSET APPOINTMENT
  1001.                JMP     SHORT CALENDAR_END
  1002.  
  1003. CK_CAL_F7:     CMP     AL,F7_SCAN              ; or F6, go directly
  1004.                JNZ     CAL_DISPATCH            ; to Journal
  1005.  
  1006.                MOV     STATE,OFFSET JOURNAL
  1007.                JMP     SHORT CALENDAR_END
  1008.  
  1009. GOTO_NOTE:     MOV     STATE,OFFSET APPOINTMENT
  1010.                CALL    CK_DATE
  1011.                MOV     APP_CURSOR,A_NOTE_CURSOR
  1012.                MOV     APP_INDEX,APP_NOTE
  1013.                JMP     SHORT CALENDAR_END
  1014.  
  1015. GOTO_APP:      MOV     STATE,OFFSET APPOINTMENT
  1016.                JMP     SHORT CALENDAR_END
  1017.  
  1018. CAL_DISPATCH:  MOV     SI,YEAR_CAL             ;Pass variables in registers
  1019.                MOV     DL,DAY_CAL              ; to calendar keyboard
  1020.                MOV     DH,MONTH_CAL            ; functions.
  1021.                MOV     BL,WEEKDAY
  1022.                MOV     BH,LAST_DAY
  1023.                MOV     DI,OFFSET CTABLE
  1024.                MOV     CX,CTABLE_LEN
  1025.                CALL    DISPATCH
  1026.                CMP     EXIT_FLAG,1
  1027.                JZ      CALENDAR_END
  1028.                JMP     CALENDAR
  1029.  
  1030. CALENDAR_DONE: MOV     EXIT_FLAG,1             ;Tell MAIN to exit.
  1031. CALENDAR_END:  RET
  1032.  
  1033. ;----------------------------------------------;
  1034. ; INPUT: SI=YEAR_CAL; DL=DAY_CAL; DH=MONTH_CAL; BL=WEEKDAY; BH=LAST_DAY
  1035.  
  1036. CTODAY:        MOV     SI,YEAR_TODAY           ;Today's date.
  1037.                MOV     DX,DAY_MON_TODAY
  1038.                JMP     SHORT CFUNC_UPDATE
  1039.  
  1040. CPGDN:         INC     DH                      ;Next month.
  1041.                CMP     DH,12                   ;Past Dec?
  1042.                JBE     CFUNC_UPDATE
  1043.                MOV     DH,1                    ;Jan.
  1044.                INC     SI                      ;Next year.
  1045.                JMP     SHORT CK_YEAR
  1046.  
  1047. CPGUP:         DEC     DH                      ;Previous month.
  1048.                JNZ     CFUNC_UPDATE            ;Before Jan?
  1049.                MOV     DH,12                   ;Dec.
  1050.                DEC     SI                      ;Previous year.
  1051.                JMP     SHORT CK_YEAR
  1052.  
  1053. CCTRLPGDN:     INC     SI                      ;Next year.
  1054.                JMP     SHORT CK_YEAR
  1055.  
  1056. CCTRLPGUP:     DEC     SI                      ;Previous year.
  1057.  
  1058. CK_YEAR:       CMP     SI,10000                ;Stay within Gregorian
  1059.                JAE     CFUNC_END               ; calendar.
  1060.                CMP     SI,1582
  1061.                JA      CFUNC_UPDATE
  1062.                JMP     SHORT CFUNC_END
  1063.  
  1064. CLEFT:         DEC     DL                      ;Previous day.
  1065.                JNZ     CFUNC_UPDATE
  1066.                JMP     SHORT CFUNC_END
  1067.  
  1068. CRIGHT:        INC     DL                      ;Next day.
  1069.                CMP     DL,BH
  1070.                JBE     CFUNC_UPDATE
  1071.                JMP     SHORT CFUNC_END
  1072.  
  1073. CUP:           MOV     AL,7                    
  1074.                SUB     AL,BL                   ;Adjust for weekday.
  1075.                CMP     DL,AL                   ;If first week, ignore
  1076.                JBE     CFUNC_END
  1077.                SUB     DL,7                    ;Previous week.
  1078.                JA      CFUNC_UPDATE
  1079.                MOV     DL,1                    ;First day, if out of bounds.
  1080.                JMP     SHORT CFUNC_UPDATE
  1081.  
  1082. CDOWN:         MOV     CL,7
  1083.                MOV     AL,CL
  1084.                SUB     AL,BL
  1085. FIND_BOTTOM:   ADD     AL,CL                   ;Find last week row.
  1086.                CMP     AL,BH
  1087.                JBE     FIND_BOTTOM
  1088.                SUB     AL,CL                   
  1089.                CMP     DL,AL
  1090.                JA      CFUNC_END               ;Ignore if on last row.
  1091.                ADD     DL,7                    ;Next week.
  1092.                CMP     DL,BH
  1093.                JBE     CFUNC_UPDATE
  1094.                MOV     DL,BH                   ;Last day if out of bounds.
  1095.                JMP     SHORT CFUNC_UPDATE
  1096.  
  1097. CCTRLHOME:     MOV     DL,1                    ;First day.
  1098.                JMP     SHORT CFUNC_UPDATE
  1099.  
  1100. CCTRLEND:      MOV     DL,BH                   ;Last day.
  1101.  
  1102. CFUNC_UPDATE:  MOV     YEAR_CAL,SI             ;Store new day/year.
  1103.                MOV     DAY_MON_CAL,DX
  1104. CFUNC_END:     RET
  1105.  
  1106. CHOME:         MOV     AL,DL                   ;Adjust for weekday.
  1107.                ADD     AL,BL
  1108.                DEC     AL
  1109.                CBW
  1110.                MOV     CL,7
  1111.                DIV     CL
  1112.                MOV     DL,1                    ;First day if at start of row.
  1113.                OR      AH,AH
  1114.                JZ      CFUNC_UPDATE
  1115.                MUL     CL
  1116.                SUB     AL,BL
  1117.                INC     AL
  1118.                JBE     CFUNC_UPDATE
  1119.                MOV     DL,AL                   ;Else go to start of row.
  1120.                JMP     CFUNC_UPDATE
  1121.  
  1122. CEND:          MOV     AL,DL                   ;Adjust for weekday.
  1123.                ADD     AL,BL
  1124.                CBW
  1125.                MOV     CL,7
  1126.                DIV     CL
  1127.                MOV     DL,BH                   ;Last day if at end of row.
  1128.                OR      AH,AH
  1129.                JZ      CFUNC_UPDATE
  1130.                MUL     CL
  1131.                ADD     AL,CL
  1132.                SUB     AL,BL
  1133.                MOV     DL,AL                   ;Else, end of row.
  1134.                CMP     DL,BH
  1135.                JBE     CFUNC_UPDATE
  1136.                MOV     DL,BH
  1137.                JMP     CFUNC_UPDATE
  1138.  
  1139. ;----------------------------------------------;
  1140. CK_DATE:       MOV     AX,DAY_MON_CAL          ;Retrieve calendar day/year.
  1141.                MOV     BX,YEAR_CAL
  1142.                CMP     REREAD_FLAG,1           ;Forced reread?
  1143.                JZ      GET_CAL
  1144.                CMP     AH,MONTH_CUR            ;Has month changed?
  1145.                JNZ     GET_CAL
  1146.                CMP     BX,YEAR_CUR             ;Has year changed?
  1147.                JNZ     GET_CAL
  1148.                CMP     STATE,OFFSET CALENDAR
  1149.                JZ      CK_DATE_END             ;If appointment screen,
  1150.                CMP     AL,DAY_CUR              ; has day changed?
  1151.                JZ      CK_DATE_END
  1152.  
  1153. GET_CAL:       MOV     REREAD_FLAG,0           ;Reset flag.
  1154.                PUSH    AX
  1155.                PUSH    BX
  1156.                CALL    PERMANENT               ;See if changes have been made
  1157.                POP     BX                      ; in appointment screen.
  1158.                POP     AX
  1159.                MOV     MONTH_CUR,AH            ;Store current day/year.
  1160.                MOV     YEAR_CUR,BX
  1161.                CALL    FIRSTDAY                ;Find first day of month.
  1162.                CALL    READ_DATA               ;Read data off of disk.
  1163.                CMP     ALARM_FLAG,1            ;Was this alarm?
  1164.                JZ      RESET_ALARM             ;If yes, leave cursor on app.
  1165.  
  1166.                MOV     A_LEFT.CURSOR,A_LEFT_CURSOR
  1167.                MOV     A_RIGHT.CURSOR,A_RIGHT_CURSOR
  1168.                MOV     A_NOTE.CURSOR,A_NOTE_CURSOR
  1169.                MOV     APP_INDEX,APP_LEFT
  1170.                MOV     APP_CURSOR,A_LEFT_CURSOR
  1171.  
  1172.                MOV     JOU_CURSOR,JOU_HOME
  1173.                MOV     JOU_INDEX,0
  1174.  
  1175. RESET_ALARM:   MOV     ALARM_FLAG,0
  1176. CK_DATE_END:   RET
  1177.  
  1178. ;----------------------------------------------;
  1179. FIRSTDAY:      MOV     SI,YEAR_CAL             ;Year.
  1180.                MOV     NUMDAYS[1],28           ;Assume this isn't a leap year.
  1181.                TEST    SI,3                    ;Year divisible by 4?
  1182.                JNZ     GETDAY                  ;Assumed right.
  1183.                MOV     NUMDAYS[1],29           ;Leap year = 29 days.
  1184. GETDAY:        MOV     BX,6                    ;Saturday,(weekday of 1/1/1583)
  1185.                MOV     AX,SI                   ;Calendar year.
  1186.                SUB     AX,1583                 ;No. years since our base year.
  1187.                ADD     BX,AX                   ;Calendar advances 1 weekday per
  1188.                                                ;  year unless leap year.
  1189.                ADD     AX,2                    ;Adj diff, so even #, if year
  1190.                MOV     CX,4                    ;  was after a leap year.
  1191.                CWD
  1192.                DIV     CX                      ;No. leap years before this.
  1193.                ADD     BX,AX                   ;Add 1 day, for each leap yr.
  1194.                CMP     SI,1700                 ;Things work normally 'til 1700.
  1195.                JL      CNVRT                   ;Not a leap year.
  1196.                MOV     AX,SI
  1197.                SUB     AX,1600                 ;Get no. years since 1600.
  1198.                MOV     CL,100
  1199.                CWD                             ;Convert to number of centuries.
  1200.                DIV     CX
  1201.                OR      DX,DX                   ;If remain=0 this is centennial.
  1202.                JNZ     DEDUCT
  1203.                TEST    AX,3                    ;If century divisible by
  1204.                JZ      DECAX                   ; 400, it is also leap year.
  1205.                MOV     NUMDAYS[1],28           ;Other centennial years have 28.
  1206. DECAX:         DEC     AX                      ;If centennial, sub 1 from cent.
  1207. DEDUCT:        SUB     BX,AX                   ;Subtract 1 weekday per century.
  1208.                CWD
  1209.                MOV     CL,4
  1210.                DIV     CX                      ;Calculate centuries mod 400.
  1211.                ADD     BX,AX                   ;Add back 1 day per 400 years.
  1212. CNVRT:         MOV     SI,OFFSET NUMDAYS       ;Add in days per month, this yr.
  1213.                XOR     AH,AH
  1214.                MOV     CL,MONTH_CAL            ;Calendar month.
  1215.                DEC     CL
  1216.                MOV     DI,CX
  1217.                MOV     DL,NUMDAYS[DI]
  1218.                MOV     LAST_DAY,DL
  1219.                JCXZ    FINAL                   ;If Jan, ready for final calc.
  1220. ADDMNTH:       LODSB
  1221.                ADD     BX,AX                   ;Add to days count.
  1222.                LOOP    ADDMNTH                 ;Cont. until prior months added.
  1223. FINAL:         MOV     AX,BX                   ;Days advanced since 1/1/1583.
  1224.                CWD
  1225.                MOV     CL,7                    ;Find no. full weeks since 1583.
  1226.                DIV     CX                      ;Weekday of 1st of cal's month.
  1227.                MOV     WEEKDAY,DL              ;Result is first day of week.
  1228.  
  1229.                MOV     AL,DAY_CAL              ;Fix last day.
  1230. FIX_CURSOR:    CMP     AL,LAST_DAY
  1231.                JBE     STORE_CURSOR2
  1232.                DEC     AL
  1233.                JMP     FIX_CURSOR
  1234. STORE_CURSOR2: MOV     DAY_CAL,AL              ;Store fix.
  1235.                MOV     DAY_CUR,AL
  1236.                CALL    STORE_DATE
  1237.                RET
  1238.  
  1239. ;----------------------------------------------;
  1240. STORE_DATE:    MOV     BP,5                    ;Five places need dates.
  1241.                MOV     DI,OFFSET CAL_DATE      ;Calendar screen.
  1242. NEXT_DATE:     PUSH    DI
  1243.                MOV     AL,MONTH_CAL            ;Month
  1244.                DEC     AL
  1245.                MOV     CX,3
  1246.                MUL     CL
  1247.                ADD     AX,OFFSET MONTHS
  1248.                MOV     SI,AX
  1249.                REP     MOVSB
  1250.                INC     DI
  1251.                CMP     BP,5
  1252.                JZ      STORE_YEAR
  1253.  
  1254.                MOV     AL,DAY_CAL              ;Number of day.
  1255.                CBW
  1256.                CALL    STORE_NUM
  1257.                MOV     AL,SPACE
  1258.                STOSB
  1259. STORE_YEAR:    MOV     AX,YEAR_CAL             ;Year.
  1260.                CALL    STORE_NUM
  1261.                MOV     AL,SPACE
  1262.                STOSB
  1263.  
  1264.                POP     DI
  1265.                CMP     BP,5
  1266.                JZ      LOOP_DATE
  1267.                ADD     DI,12
  1268.                MOV     AL,WEEKDAY
  1269.                ADD     AL,DAY_CAL
  1270.                DEC     AL
  1271.                CBW
  1272.                MOV     CL,7
  1273.                DIV     CL
  1274.                MOV     AL,AH
  1275.                MOV     CL,11
  1276.                MUL     CL
  1277.                ADD     AX,OFFSET DAYS          ;Name of weekday; ie. Mon etc.
  1278.                MOV     SI,AX
  1279.                MOV     CX,3
  1280.                REP     MOVSB
  1281.  
  1282. LOOP_DATE:     DEC     BP
  1283.                JZ      STORE_DATE_END
  1284.                MOV     DI,OFFSET APP_DATE      ;Appointment screen.
  1285.                CMP     BP,4
  1286.                JZ      NEXT_DATE
  1287.                MOV     DI,OFFSET PUR_DATE      ;Purge window.
  1288.                CMP     BP,3
  1289.                JZ      NEXT_DATE
  1290.                MOV     DI,OFFSET JOU_DATE
  1291.                CMP     BP,2
  1292.                JZ      NEXT_DATE
  1293.                MOV     DI,OFFSET REPORT_DATE
  1294.                JMP     NEXT_DATE
  1295. STORE_DATE_END:RET
  1296.  
  1297. ;----------------------------------------------;
  1298. STORE_NUM:     MOV     BX,10
  1299.                XOR     CX,CX                   ;Zero in counter.
  1300. NEXT_COUNT:    CWD                             ;Zero in high half.
  1301.                DIV     BX                      ;Divide by ten.
  1302.                ADD     DL,"0"                  ;Convert to ASCII.
  1303.                PUSH    DX                      ;Save results.
  1304.                INC     CX                      ;Also increment count.
  1305.                OR      AX,AX                   ;Are we done?
  1306.                JNZ     NEXT_COUNT              ;Continue until zero.
  1307. NEXT_NUMBER:   POP     AX                      ;Retrieve numbers.
  1308.                STOSB
  1309.                LOOP    NEXT_NUMBER
  1310.                RET
  1311.  
  1312. ;----------------------------------------------;
  1313. SCAN_DAY:      CALL    SCAN_APP                ;Find appointments.
  1314.                MOV     AL,DAY_CAL              ;Store small box char.
  1315.                CALL    STORE_BLOCKS            ; if appointment found.
  1316.                MOV     AX,YEAR_CAL
  1317.                CMP     AX,YEAR_TODAY
  1318.                JNZ     SCAN_DAY_END
  1319.                MOV     AX,DAY_MON_CAL
  1320.                CMP     AX,DAY_MON_TODAY
  1321.                JNZ     SCAN_DAY_END
  1322.                CALL    STORE_ALARMS            ;Store alarm if today.
  1323. SCAN_DAY_END:  RET
  1324.  
  1325. ;----------------------------------------------;
  1326. SCAN_APP:      PUSH    BP
  1327.                MOV     SI,OFFSET WORK_SPACE    ;Spaces in work space.
  1328.                MOV     AL,SPACE
  1329.                MOV     BP,OFFSET APP_LEFT_START   ;Scan appointments for
  1330.                MOV     CX,2                       ; non-space chars.
  1331. NEXT_COL:      PUSH    CX
  1332.                MOV     DX,APP_HEIGHT
  1333. NEXT_DAY:      MOV     DI,BP
  1334.                MOV     CX,APP_LEN
  1335.                XOR     AH,AH                   ;Mark with zero if no app.
  1336.                REP     SCASB
  1337.                JZ      TEMP_APP
  1338.                INC     AH                      ;Else, mark with one for alarm.
  1339. TEMP_APP:      MOV     [SI],AH
  1340.                INC     SI
  1341.                ADD     BP,APP_WIDTH
  1342.                DEC     DX
  1343.                JNZ     NEXT_DAY
  1344.                MOV     BP,OFFSET APP_RIGHT_START
  1345.                POP     CX
  1346.                LOOP    NEXT_COL
  1347.                POP     BP
  1348.                RET
  1349.  
  1350. ;----------------------------------------------;
  1351. ; INPUT: AL = Calendar day.
  1352. STORE_BLOCKS:  DEC     AL
  1353.                CBW
  1354.                MOV     CL,3
  1355.                SHL     AX,CL
  1356.                MOV     DI,AX
  1357.                ADD     DI,OFFSET APPOINTMENT_BLOCKS
  1358.                MOV     SI,OFFSET WORK_SPACE
  1359.                MOV     CX,2
  1360. NEXT_SET:      PUSH    CX
  1361.                MOV     DX,APP_HEIGHT / 2
  1362. NEXT_BLOCK2:   LODSW
  1363.                OR      AX,AX
  1364.                MOV     AL,SPACE                ;Store a space if no appointment.
  1365.                JZ      STORE_BLOCK
  1366.                MOV     AL,"■"                  ;Else, store little block char.
  1367. STORE_BLOCK:   STOSB
  1368.                DEC     DX
  1369.                JNZ     NEXT_BLOCK2
  1370.                ADD     DI,(BLOCK_COUNT / 2) - 8
  1371.                POP     CX
  1372.                LOOP    NEXT_SET
  1373.                RET
  1374.  
  1375. ;----------------------------------------------;
  1376. ALARMS         DB      APP_HEIGHT * 2 DUP (0)
  1377. WORK_SPACE     DB      APP_HEIGHT * 2 DUP (?)
  1378.  
  1379. STORE_ALARMS:  MOV     SI,OFFSET WORK_SPACE    ;Copy results of work space
  1380.                MOV     DI,OFFSET ALARMS        ; into alarm array.
  1381.                MOV     CX,SIZE ALARMS / 2
  1382.                REP     MOVSW
  1383.                RET
  1384.  
  1385. TODAY_FLAG     EQU     001B                    ;Data applies to today.
  1386. CAL_FLAG       EQU     010B                    ;Data applies to calendar.
  1387. APP_FLAG       EQU     100B                    ;Data applies to appointment.
  1388.  
  1389. READ_DATA:     CMP     STATE,OFFSET JOURNAL
  1390.                JNZ     READ_DATA2
  1391.                JMP     READ_JOURNAL
  1392.  
  1393. READ_DATA2:    MOV     DI,OFFSET APPOINTMENT_BLOCKS
  1394.                MOV     CX,BLOCK_COUNT / 2
  1395.                MOV     AX,SPACE SHL 8 + SPACE
  1396.                REP     STOSW                   ;Spaces in Appointment blocks.
  1397.  
  1398.                MOV     BP,APP_HEIGHT
  1399.                MOV     BX,APP_LEN
  1400.                MOV     DI,OFFSET APP_LEFT_START
  1401. NEXT_BLANK:    MOV     CX,BX
  1402.                REP     STOSB
  1403.                ADD     DI,APP_COL_SPACE
  1404.                MOV     CX,BX
  1405.                REP     STOSB                   ;Spaces in Appointment book.
  1406.                ADD     DI,APP_ROW_SPACE
  1407.                DEC     BP
  1408.                JNZ     NEXT_BLANK
  1409.  
  1410.                MOV     BP,3
  1411.                MOV     BX,NOTE_LEN
  1412.                MOV     DI,OFFSET NOTEPAD
  1413. NEXT_PAD:      MOV     CX,BX
  1414.                REP     STOSB                   ;Spaces in Notepad.
  1415.                ADD     DI,APP_NOTE_SPACE
  1416.                DEC     BP
  1417.                JNZ     NEXT_PAD
  1418.  
  1419.                MOV     DI,OFFSET ALARMS
  1420.                MOV     CX,SIZE ALARMS / 2
  1421.                REP     STOSW                   ;Spaces in Alarms.
  1422.  
  1423.                CALL    OPEN                    ;Open data file.
  1424.                JBE     READ_DONE               ;If none, then done.
  1425.  
  1426. NEXT_READ:     CALL    READ_DATE               ;Read the date.
  1427.                JBE     READ_FAILED
  1428.                OR      AX,AX
  1429.                JZ      READ_END
  1430.  
  1431.                XOR     BP,BP                   ;Initialize date flag.
  1432.                CMP     CX,YEAR_TODAY           ;Data same day/month/year
  1433.                JNZ     CK_YEAR_CAL             ; as today?
  1434.                CMP     DX,DAY_MON_TODAY
  1435.                JNZ     CK_YEAR_CAL
  1436.                OR      BP,TODAY_FLAG           ;If yes, today.
  1437.  
  1438. CK_YEAR_CAL:   CMP     CX,YEAR_CAL             ;Same as day/month/year
  1439.                JNZ     CK_READ                 ; as calendar?
  1440.                CMP     DX,DAY_MON_CAL
  1441.                JNZ     CK_MON_CAL
  1442.                OR      BP,CAL_FLAG OR APP_FLAG ;If yes, then applies to
  1443.                JMP     SHORT DO_READ           ; calendar and appointment.
  1444.  
  1445. CK_MON_CAL:    CMP     DH,MONTH_CAL            ;Same as month/year only.
  1446.                JNZ     CK_READ
  1447.                OR      BP,CAL_FLAG             ;If yes, applies to calendar.
  1448.  
  1449. CK_READ:       OR      BP,BP                   ;Does data apply to anything?
  1450.                JNZ     DO_READ
  1451.                CALL    NEXT_RECORD             ;If no, bump file pointer
  1452.                JBE     READ_FAILED             ; to next record.
  1453.                JMP     NEXT_READ
  1454.  
  1455. DO_READ:       CALL    READ_APP                ;If applies, read in the data.
  1456.                JBE     READ_FAILED
  1457.  
  1458.                TEST    BP,APP_FLAG             ;Apply to appointments?
  1459.                JZ      CK_TODAY_CAL
  1460.                CALL    MOVE_APP                ;If yes, move data into app.
  1461.  
  1462. CK_TODAY_CAL:  CALL    SCAN_DTA                ;Scan the data for appointments.
  1463.                TEST    BP,TODAY_FLAG           ;Does it apply to today.
  1464.                JZ      CK_MON_CAL2
  1465.                CALL    STORE_ALARMS            ;If yes, store alarms.
  1466.  
  1467. CK_MON_CAL2:   TEST    BP,CAL_FLAG             ;Apply to calendar?
  1468.                JZ      NEXT_READ
  1469.                MOV     AL,BYTE PTR DTA.DATE_BINARY + 2
  1470.                CALL    STORE_BLOCKS            ;If yes, store small block chars.
  1471.                JMP     NEXT_READ
  1472.  
  1473. READ_END:      MOV     AH,3EH                  ;Close data file.
  1474.                CALL    INT21_IO
  1475. READ_DONE:     RET
  1476.  
  1477. READ_FAIL:     CALL    FAILED                  ;If failed, display message.
  1478.                RET
  1479. READ_FAILED:   CALL    FAILED_CLOSE
  1480.                RET
  1481.  
  1482.  
  1483.  
  1484. READ_JOURNAL:  MOV     DI,OFFSET DTA.DATA_TEXT
  1485.                MOV     CX,SIZE JOU_FIELDS / 2
  1486.                MOV     AX,SPACE SHL 8 + SPACE
  1487.                REP     STOSW
  1488.  
  1489.                CALL    STORE_JOURNAL
  1490.                CALL    OPEN
  1491.                JBE     READ_DONE
  1492.  
  1493. NEXT_READ_JOU: CALL    READ_DATE
  1494.                JBE     READ_FAILED
  1495.                OR      AX,AX
  1496.                JZ      READ_END
  1497.  
  1498.                CMP     CX,YEAR_CAL
  1499.                JNZ     JOU_RECORD
  1500.                CMP     DX,DAY_MON_CAL
  1501.                JNZ     JOU_RECORD
  1502.                MOV     DX,OFFSET DTA.DATE_ASCII
  1503.                MOV     CX,SIZE DATE_ASCII+SIZE JOU_FIELDS
  1504.                MOV     AH,3FH
  1505.                CALL    INT21_IO                ;Read data record.
  1506.                JBE     READ_FAILED
  1507.                CALL    STORE_JOURNAL
  1508.                JMP     READ_END
  1509.  
  1510. JOU_RECORD:    CALL    NEXT_RECORD
  1511.                JBE     READ_FAILED
  1512.                JMP     NEXT_READ_JOU
  1513.  
  1514. ;----------------------------------------------;
  1515. SCAN_DTA:      PUSH    BP
  1516.                MOV     SI,OFFSET WORK_SPACE
  1517.                MOV     AL,SPACE
  1518.                MOV     BP,OFFSET DTA.DATA_TEXT
  1519.                MOV     CX,2
  1520. NEXT_DTA:      PUSH    CX
  1521.                MOV     DX,APP_HEIGHT           ;Scan data read off disk
  1522. NEXT_DTA2:     MOV     DI,BP                   ; and store a 1 in work space
  1523.                MOV     CX,APP_LEN              ; if non-space char.
  1524.                XOR     AH,AH
  1525.                REP     SCASB
  1526.                JZ      TEMP_APP2
  1527.                INC     AH
  1528. TEMP_APP2:     MOV     [SI],AH
  1529.                INC     SI
  1530.                ADD     BP,APP_LEN * 2
  1531.                DEC     DX
  1532.                JNZ     NEXT_DTA2
  1533.                MOV     BP,OFFSET DTA.DATA_TEXT + APP_LEN
  1534.                POP     CX
  1535.                LOOP    NEXT_DTA
  1536.                POP     BP
  1537.                RET
  1538.  
  1539. ;----------------------------------------------;
  1540. MOVE_APP:      MOV     SI,OFFSET DTA.DATA_TEXT
  1541.                MOV     DI,OFFSET APP_LEFT_START
  1542.                MOV     DX,APP_HEIGHT
  1543. NEXT_MOVE:     MOV     CX,APP_LEN
  1544.                REP     MOVSB                   ;Move DTA appointments into
  1545.                ADD     DI,APP_COL_SPACE        ; screen app. storage space.
  1546.                MOV     CX,APP_LEN
  1547.                REP     MOVSB
  1548.                ADD     DI,APP_ROW_SPACE
  1549.                DEC     DX
  1550.                JNZ     NEXT_MOVE
  1551.  
  1552.                MOV     SI,OFFSET DTA.NOTEPAD_TEXT
  1553.                MOV     DI,OFFSET NOTEPAD       ;Move DTA Notepad into
  1554.                MOV     CX,NOTEPAD_LEN          ; screen Notepad space.
  1555.                REP     MOVSB
  1556.                RET
  1557.  
  1558. ;***************************************************************************;
  1559. APP_BOUNDS     STRUC                           ;Cursor bounds in 3 sections.
  1560. COL_HOME       DB      ?
  1561. COL_END        DB      ?
  1562. ROW_HOME       DB      ?
  1563. ROW_END        DB      ?
  1564. CURSOR         DW      ?
  1565. APP_BOUNDS     ENDS
  1566.  
  1567. APP_LEFT       EQU     0
  1568. APP_RIGHT      EQU     SIZE APP_BOUNDS
  1569. APP_NOTE       EQU     APP_RIGHT + SIZE APP_BOUNDS
  1570. APP_INDEX      DW      APP_LEFT                ;Section index.
  1571.  
  1572. A_LEFT_CURSOR  EQU     4 SHL 8 + 12            ;Home cursor positions.
  1573. A_RIGHT_CURSOR EQU     4 SHL 8 + 48
  1574. N_ROW          EQU     4 + APP_HEIGHT + 1
  1575. A_NOTE_CURSOR  EQU     N_ROW SHL 8 + 4
  1576.  
  1577. BOUNDS         LABEL   BYTE
  1578. A_LEFT  APP_BOUNDS < 12, 12 + APP_LEN, 4, 4 + APP_HEIGHT - 1, A_LEFT_CURSOR >
  1579. A_RIGHT APP_BOUNDS < 48, 48 + APP_LEN, 4, 4 + APP_HEIGHT - 1, A_RIGHT_CURSOR >
  1580. A_NOTE  APP_BOUNDS <4,4+NOTE_LEN,N_ROW,4+APP_HEIGHT+NOTE_HEIGHT,A_NOTE_CURSOR >
  1581.  
  1582. APP_CURSOR     LABEL   WORD
  1583. APP_CUR_COL    DB      12                      ;Appointment cursor position.
  1584. APP_CUR_ROW    DB       4
  1585.  
  1586. REPAINT_FLAG   DB      1                       ; 1 = Repaint the screen.
  1587.  
  1588.  
  1589. ATABLE         DB  3CH,        3DH,    3EH,    3FH,       40H,       59H
  1590.                DB  63H,        4BH,    4DH,    48H,       50H,       47H
  1591.                DB  4FH,        49H,    51H,    84H,       76H,       77H
  1592.                DB  75H,        73H,    74H,    0FH,       53H
  1593. ATABLE_LEN     EQU     $ - ATABLE
  1594.                DW  SAVE,       ATODAY, PPURGE, PRINT,     CLEAR,     SHIFT_CLEAR
  1595.                DW  CTRL_CLEAR, ALEFT,  ARIGHT, AUP,       ADOWN,     AHOME
  1596.                DW  AEND,       APGUP,  APGDN,  ACTRLPGUP, ACTRLPGDN, ACTRLHOME
  1597.                DW  ACTRLEND,   AHOME,  AEND,   SHIFT_TAB, ADEL
  1598.  
  1599. APPOINTMENT:   MOV     SI,OFFSET SCH_DAT
  1600.                CALL    APPEND
  1601.  
  1602.                CALL    CK_DATE                 ;Check if date changed.
  1603.                CMP     REPAINT_FLAG,1
  1604.                JNZ     NEXT_APPOINT
  1605.  
  1606.                MOV     SI,OFFSET APP_MENU      ;Display appointment screen.
  1607.                CALL    POP_MENU
  1608.                MOV     REPAINT_FLAG,0
  1609.  
  1610. NEXT_APPOINT:  MOV     DX,APP_CURSOR
  1611.                CALL    SET_CURSOR
  1612.                CALL    GETKEY                  ;Get a keystroke.
  1613.                CMP     EXIT_FLAG,1             ;Exit if hotkey.
  1614.                JZ      APPOINT_END
  1615.  
  1616.                CMP     AL,SHIFT_F7_SCAN
  1617.                JNZ     CK_APP_F7
  1618.                CALL    PERMANENT
  1619.                MOV     STATE,OFFSET JOURNAL
  1620.                JMP     SHORT APPOINT_END
  1621.  
  1622. CK_APP_F7:     CMP     AL,F7_SCAN
  1623.                JNZ     CK_APP_ESC
  1624.                CALL    PERMANENT
  1625.                MOV     STATE,OFFSET CALENDAR
  1626.                JMP     SHORT APPOINT_END
  1627.  
  1628. CK_APP_ESC:    CMP     AL,ESC_SCAN             ;Back to calendar if Esc.
  1629.                JNZ     APP_DISPATCH
  1630.                CALL    PERMANENT
  1631.                MOV     STATE,OFFSET CALENDAR
  1632.                JMP     SHORT APPOINT_END
  1633. APP_DISPATCH:  CALL    CALC_APP_ADDR           ;Get cursor bounds.
  1634.                MOV     BP,APP_INDEX
  1635.                MOV     BX,WORD PTR BOUNDS[BP]
  1636.                OR      AH,AH                   ;Extended scan code?
  1637.                JZ      GOT_DISPATCH
  1638.                CALL    CK_ENTRY
  1639.                JMP     NEXT_APPOINT
  1640.  
  1641. GOT_DISPATCH:  MOV     DI,OFFSET ATABLE
  1642.                MOV     CX,ATABLE_LEN
  1643.                CALL    DISPATCH
  1644.                CMP     EXIT_FLAG,1
  1645.                JNZ     APPOINTMENT
  1646. APPOINT_END:   MOV     REPAINT_FLAG,1          ;Flag to repaint screen.
  1647.                CALL    PERMANENT               ;Check for changes.
  1648.                CALL    SCAN_DAY                ;Scan appointments.
  1649.                RET
  1650.  
  1651. ;----------------------------------------------;
  1652. ; INPUT:  DX = Cursor address; OUTPUT: SI -> Start of row.
  1653. CALC_APP_ADDR: PUSH    AX
  1654.                MOV     CX,DX
  1655.                SUB     CH,4                    ;Appointments start on line 4.
  1656.                MOV     AX,APP_WIDTH
  1657.                MUL     CH
  1658.                MOV     SI,AX
  1659.                XOR     CH,CH
  1660.                ADD     SI,CX
  1661.                ADD     SI,OFFSET APP_START
  1662.                POP     AX
  1663.                RET
  1664.  
  1665. ;----------------------------------------------;
  1666. ; INPUT: SI -> appointments; DX=Cursor; BP=APP_INDEX; BH=COL_END; BL=COL_HOME
  1667.  
  1668. CK_ENTRY:      XCHG    AH,AL
  1669.                CMP     AL,TAB                  ;Tab?
  1670.                JNZ     CK_BACKSPACE
  1671. SHIFT_TAB:     MOV     CX,SIZE APP_BOUNDS
  1672.                MOV     BX,BP                   ;Save index.
  1673.                MOV     AH,2
  1674.                INT     16H                     ;Get shift status.
  1675.                TEST    AL,11B                  ;Left or Right Shift?
  1676.                JZ      DO_TAB
  1677.                NEG     CX
  1678. DO_TAB:        MOV     AX,APP_NOTE
  1679.                ADD     BP,CX
  1680.                JNS     CK_HIGH
  1681.                MOV     BP,AX
  1682. CK_HIGH:       CMP     BP,AX
  1683.                JBE     NEW_FIELD
  1684.                XOR     BP,BP
  1685. NEW_FIELD:     MOV     APP_INDEX,BP            ;New section.
  1686.                MOV     BOUNDS.CURSOR[BX],DX    ;Save current cursor position.
  1687.                MOV     DX,BOUNDS.CURSOR[BP]    ;Get new cursor position.
  1688.                JMP     SHORT ENTRY_UPDATE
  1689.  
  1690. CK_BACKSPACE:  CMP     AL,8                    ;Backspace?
  1691.                JNZ     CK_PAD_CR
  1692.                CMP     DL,BL
  1693.                JZ      ENTRY_END
  1694.                DEC     SI                      ;Move back one space.
  1695.                DEC     DL
  1696.                MOV     APP_CURSOR,DX           ;Save cursor position.
  1697.                CALL    ADEL                    ;Delete that character.
  1698.                JMP     SHORT ENTRY_END
  1699.  
  1700. CK_PAD_CR:     CMP     AL,CR                   ;Carriage return?
  1701.                JNZ     APP_ASCII
  1702.                MOV     DL,BL
  1703.                CMP     DH,BOUNDS.ROW_END[BP]   ;Move to start of line.
  1704.                JZ      ENTRY_UPDATE
  1705.                INC     DH                      ;Next row if not at bottom.
  1706.                JMP     SHORT ENTRY_UPDATE
  1707.  
  1708. APP_ASCII:     CMP     AL,SPACE                ;Text character?
  1709.                JB      ENTRY_END
  1710.                INC     DL                      ;Next column.
  1711.                SUB     BH,DL
  1712.                JC      ENTRY_END               ;If last column, ignore.
  1713.                JZ      STORE_APP               ;If next to last column, store.
  1714.                MOV     CL,BH
  1715.                XOR     CH,CH                   
  1716.                ADD     SI,CX
  1717.                MOV     DI,SI
  1718.                DEC     SI
  1719.                STD
  1720.                REP     MOVSB                   ;Else, insert mode so shove
  1721.                CLD                             ; everything in front up one.
  1722.                INC     SI
  1723. STORE_APP:     MOV     [SI],AL                 ;Store character.
  1724.  
  1725. ENTRY_CHANGE:  MOV     MODIFY_FLAG,1           ;Flag that change made.
  1726. ENTRY_UPDATE:  MOV     APP_CURSOR,DX           ;Store new cursor position.
  1727.  
  1728.                MOV     SI,OFFSET APP_START
  1729.                CALL    DISPLAY_LINE            ;Display just that changed line
  1730.                                                ; for better response time.
  1731. ENTRY_END:     RET
  1732.  
  1733. ;----------------------------------------------;
  1734. ACTRLHOME:     MOV     DL,BL                   ;Beginning of field.
  1735.                JMP     SHORT DO_HOME
  1736.  
  1737. AHOME:         CMP     DL,BL                   ;Beginning of field unless
  1738.                MOV     DL,BL                   ; already there, then go
  1739.                JNZ     ENTRY_UPDATE            ; to section home.
  1740. DO_HOME:       MOV     DH,BOUNDS.ROW_HOME[BP]
  1741.                JMP     ENTRY_UPDATE
  1742.  
  1743. ACTRLEND:      MOV     DL,BH                   ;End of field
  1744.                JMP     SHORT DO_END
  1745.  
  1746. AEND:          CALL    GET_WORD
  1747.                CMP     DI,SI
  1748.                JZ      DO_END1
  1749.                MOV     BX,DI
  1750.                MOV     CX,SI
  1751.                SUB     BX,CX
  1752.                ADD     DL,BL
  1753.                JMP     ENTRY_UPDATE
  1754.  
  1755. DO_END1:       MOV     DL,BH
  1756.  
  1757. DO_END:        MOV     DH,BOUNDS.ROW_END[BP]
  1758.                JMP     ENTRY_UPDATE
  1759.  
  1760. ALEFT:         CMP     DL,BL                   ;Left one space unless
  1761.                JNZ     DO_LEFT                 ; already column home.
  1762.                CMP     BP,APP_RIGHT
  1763.                JNZ     ENTRY_END
  1764.                MOV     APP_INDEX,APP_LEFT      ;If in col home of right section,
  1765.                SUB     DL,6                    ; go to left section.
  1766. DO_LEFT:       DEC     DL
  1767.                JMP     ENTRY_UPDATE
  1768.  
  1769. ARIGHT:        INC     DL                      ;Right on space unless
  1770.                CMP     DL,BH                   ; already column end.
  1771.                JBE     ENTRY_UPDATE
  1772.                CMP     BP,APP_LEFT
  1773.                JNZ     ENTRY_END
  1774.                MOV     APP_INDEX,APP_RIGHT     ;If in col end of left section,
  1775.                ADD     DL,6                    ; go to right section.
  1776.                JMP     ENTRY_UPDATE
  1777.  
  1778. ADOWN:         CMP     DH,BOUNDS.ROW_END[BP]   ;If at bottom, go and not
  1779.                JNZ     UPDATE_DOWN             ; in Notepad, go to Notepad.
  1780.                CMP     BP,APP_NOTE
  1781.                JZ      ENTRY_END
  1782.                INC     DH                      ;Else, next row.
  1783.                MOV     APP_INDEX,APP_NOTE
  1784. UPDATE_DOWN:   INC     DH
  1785.                JMP     ENTRY_UPDATE
  1786.  
  1787. AUP:           CMP     DH,BOUNDS.ROW_HOME[BP]  ;If in top row of NotePad
  1788.                JNZ     DO_UP                   ; go to either left or right
  1789.                CMP     BP,APP_NOTE             ; section.
  1790.                JNZ     ENTRY_END
  1791.                DEC     DH
  1792.                MOV     BP,APP_RIGHT
  1793.                CMP     DL,BOUNDS.COL_HOME[BP]
  1794.                JAE     UPDATE_UP
  1795.                MOV     BP,APP_LEFT
  1796.                MOV     BX,WORD PTR BOUNDS[BP]
  1797.                CMP     DL,BL
  1798.                JA      CK_UP_END
  1799.                MOV     DL,BL
  1800.                JMP     SHORT UPDATE_UP
  1801. CK_UP_END:     CMP     DL,BH
  1802.                JBE     UPDATE_UP
  1803.                MOV     DL,BH
  1804. UPDATE_UP:     MOV     APP_INDEX,BP
  1805. DO_UP:         DEC     DH                      ;Else, just decrement row.
  1806.                JMP     ENTRY_UPDATE
  1807.  
  1808. ADEL:          SUB     BH,DL                   ;Ignore if in last column.
  1809.                MOV     CL,BH
  1810.                XOR     CH,CH
  1811.                JCXZ    ADEL_END
  1812.                MOV     DI,SI
  1813.                INC     SI
  1814.                REP     MOVSB                   ;Else, move everything to right
  1815.                MOV     SI,OFFSET APP_START
  1816.                CALL    DISPLAY_LINE            ; of cursor left one space.
  1817.                MOV     MODIFY_FLAG,1
  1818. ADEL_END:      RET
  1819.  
  1820. ;---------------------------;
  1821.  
  1822. GET_WORD:      MOV     CL,BH
  1823.                SUB     CL,DL
  1824.                XOR     CH,CH
  1825.                MOV     DI,SI
  1826.                ADD     DI,CX
  1827.  
  1828.                MOV     CL,BH
  1829.                SUB     CL,BL
  1830.                XOR     CH,CH
  1831.  
  1832. GET_WORD2:     CMP     BYTE PTR [DI-1],SPACE
  1833.                JNZ     GOT_WORD
  1834.                DEC     DI
  1835.                LOOP    GET_WORD2
  1836. GOT_WORD:      RET
  1837.  
  1838. ;----------------------------------------------;
  1839. ATODAY:        CALL    PERMANENT
  1840.                MOV     SI,YEAR_TODAY
  1841.                MOV     YEAR_CAL,SI             ;Go to today.
  1842.                MOV     DX,DAY_MON_TODAY
  1843.                MOV     DAY_MON_CAL,DX
  1844.                JMP     SHORT DAY_UPDATE
  1845.  
  1846. APGUP:         CALL    PERMANENT
  1847. PPGUP:         MOV     AL,-1                   ;Previous day.
  1848.                JMP     SHORT CK_DAY
  1849.  
  1850. APGDN:         CALL    PERMANENT
  1851. PPGDN:         MOV     AL,1                    ;Next day.
  1852. CK_DAY:        MOV     DL,DAY_CAL
  1853.                ADD     DL,AL
  1854.                JZ      NEW_MONTH
  1855.                CMP     DL,LAST_DAY             ;Past month bounds?
  1856.                JA      NEW_MONTH
  1857. UPDATE_MONTH:  MOV     DAY_CAL,DL              ;If no, OK.
  1858.                JMP     SHORT DAY_UPDATE
  1859.  
  1860. NEW_MONTH:     MOV     DAY_CAL,1               ;Move to new month.
  1861.                JA      PCTRLPGDN
  1862.                MOV     DAY_CAL,31
  1863.                JMP     SHORT PCTRLPGUP
  1864.  
  1865. ACTRLPGUP:     CALL    PERMANENT
  1866. PCTRLPGUP:     MOV     AX,-1                   ;Previous month.
  1867.                JMP     SHORT CK_MONTH
  1868.  
  1869. ACTRLPGDN:     CALL    PERMANENT
  1870. PCTRLPGDN:     MOV     AX,1                    ;Next month.
  1871. CK_MONTH:      MOV     DH,MONTH_CAL
  1872.                ADD     DH,AL
  1873.                JNZ     CK_MONTH2
  1874.                MOV     DH,12                   ;Past year bounds?
  1875.                JMP     SHORT CK_YEAR2
  1876. CK_MONTH2:     CMP     DH,12
  1877.                JBE     UPDATE_MONTH2
  1878.                MOV     DH,1
  1879.                JMP     SHORT CK_YEAR2
  1880. UPDATE_MONTH2: MOV     MONTH_CAL,DH
  1881.                JMP     SHORT DAY_UPDATE
  1882.  
  1883. CK_YEAR2:      MOV     MONTH_CAL,DH
  1884.                MOV     SI,YEAR_CAL
  1885.                ADD     SI,AX                   ;Next/Previous year.
  1886.                CMP     SI,10000
  1887.                JAE     DAY_END
  1888.                CMP     SI,1582                 ;Check bounds.
  1889.                JB      DAY_END
  1890.                MOV     YEAR_CAL,SI
  1891.  
  1892. DAY_UPDATE:    MOV     REPAINT_FLAG,1          ;Repaint the screen.
  1893. DAY_END:       RET
  1894.  
  1895. ;----------------------------------------------;
  1896. CLEAR:         MOV     DL,BL
  1897.                CALL    CALC_APP_ADDR
  1898.                MOV     DI,SI                   ;Appointment address line.
  1899.                MOV     CX,BX
  1900.                SUB     CH,CL
  1901.                MOV     CL,CH
  1902.                XOR     CH,CH
  1903.                MOV     AL,SPACE                ;Store spaces.
  1904.                REP     STOSB
  1905.                MOV     APP_CURSOR,DX           ;Home cursor.
  1906.                MOV     BOUNDS.CURSOR[BP],DX
  1907.                MOV     APP_INDEX,BP
  1908.                JMP     SHORT F6_END
  1909.  
  1910. SHIFT_CLEAR:   MOV     CX,WORD PTR BOUNDS.ROW_HOME[BP]
  1911.                MOV     DH,CH
  1912.                SUB     CH,CL
  1913.                MOV     CL,CH
  1914.                XOR     CH,CH
  1915.                INC     CX
  1916. NEXT_SHIFT_F6: PUSH    CX                      ;Rows in section.
  1917.                CALL    CLEAR                   ;Clear all rows.
  1918.                DEC     DH
  1919.                POP     CX
  1920.                LOOP    NEXT_SHIFT_F6
  1921.                JMP     SHORT F6_END
  1922.  
  1923. CTRL_CLEAR:    MOV     BP,APP_NOTE             ;Start with Notepad.
  1924.                MOV     CX,3                    ;Three sections to clear.
  1925. NEXT_CTRL_F6:  PUSH    CX
  1926.                MOV     BX,WORD PTR BOUNDS[BP]
  1927.                CALL    SHIFT_CLEAR             ;Clear section.
  1928.                SUB     BP,SIZE APP_BOUNDS
  1929.                POP     CX
  1930.                LOOP    NEXT_CTRL_F6
  1931.  
  1932. F6_END:        MOV     MODIFY_FLAG,1
  1933.                MOV     REPAINT_FLAG,1
  1934.                RET
  1935.  
  1936. ;----------------------------------------------;
  1937. ; INPUT: DX = Cursor position; SI -> Storage.
  1938. DISPLAY_LINE:  MOV     AL,DH
  1939.                SUB     AL,4                    ;Calc start of app. line
  1940.                MOV     CX,APP_WIDTH            ; to display.
  1941.                MUL     CL
  1942.                ADD     SI,AX
  1943.                MOV     AL,DH
  1944.                XOR     AH,AH
  1945.                CALL    CALC_ADDR               ;Calc corresponding display
  1946.                PUSH    ES                      ; address.
  1947.                MOV     DX,STATUS_REG
  1948.                MOV     ES,VIDEO_SEG
  1949.                MOV     BH,COLOR.B
  1950.                DEC     CX
  1951. NEXT_LINE:     LODSB                           ;Display line.
  1952.                CALL    WRITE_SCREEN
  1953.                LOOP    NEXT_LINE
  1954.                POP     ES
  1955.                RET
  1956.  
  1957. ;***************************************************************************;
  1958. DATEONLY_FLAG  DB      ?                       ; =1 if purge date only.
  1959.  
  1960. PTABLE         DB  49H,   51H,   84H,       76H,       3DH
  1961. PTABLE_LEN     EQU     $ - PTABLE
  1962.                DW  PPGUP, PPGDN, PCTRLPGUP, PCTRLPGDN, CTODAY
  1963.  
  1964. PPURGE:        PUSH    YEAR_CAL                ;Preserve calendar variables.
  1965.                PUSH    DAY_MON_CAL
  1966.                PUSH    YEAR_CUR
  1967.                PUSH    DAY_MON_CUR
  1968.                CALL    HIDE_CURSOR
  1969.  
  1970. NEXT_F4:       CALL    FIRSTDAY                ;Store purge date in window.
  1971.                MOV     AX,1
  1972.                CALL    CALC_ADDR
  1973.                ADD     DI,9 * 2
  1974.                MOV     SI,OFFSET PURGE_MSG
  1975.                CALL    POP_WINDOW              ;Display purge window.
  1976.                CALL    GETKEY                  ;Get a keystroke.
  1977.                JC      F4_DONE                 ;If Esc, exit.
  1978.                MOV     DATEONLY_FLAG,0         ;Assume F7.
  1979.                CMP     AL,F7_SCAN              ;Is it F7?
  1980.                JZ      CK_APPEND
  1981.                MOV     DATEONLY_FLAG,1         ;Assume F8.
  1982.                CMP     AL,F8_SCAN              ;Is it F8.
  1983.                JZ      CK_APPEND
  1984.  
  1985.                MOV     DI,OFFSET PTABLE
  1986.                MOV     CX,PTABLE_LEN
  1987.                CALL    DISPATCH
  1988.                CMP     EXIT_FLAG,1
  1989.                JNZ     NEXT_F4
  1990.                JMP     SHORT F4_DONE
  1991.  
  1992. F4_END:        MOV     REREAD_FLAG,1
  1993.  
  1994. F4_DONE:       POP     DAY_MON_CUR             ;Restore calendar variables.
  1995.                POP     YEAR_CUR
  1996.                POP     DAY_MON_CAL
  1997.                POP     YEAR_CAL
  1998.                CALL    FIRSTDAY                ;Fix calendar and appointment
  1999.                MOV     REPAINT_FLAG,1          ; ASCII date; repaint screen.
  2000.                RET
  2001.  
  2002. ;----------------------------------------------;
  2003. ARCHIVE_FLAG   DB      0                       ; =1 if archive.
  2004. READ_HANDLE    DW      -1                      ;File handles.
  2005. WRITE_HANDLE   DW      -1
  2006. ARCHIVE_HANDLE DW      -1
  2007. RECORD_SIZE    DW      ?                       ;Size of Jou or App data record.
  2008.  
  2009. CK_APPEND:     MOV     ARCHIVE_FLAG,0          ;Reset archive flag.
  2010.                MOV     AX,6
  2011.                CALL    CALC_ADDR
  2012.                ADD     DI,40 * 2
  2013.                MOV     SI,OFFSET ARCHIVE_MSG
  2014.                CALL    POP_WINDOW              ;Display archive window.
  2015.  
  2016. NEXT_APPEND:   CALL    GETKEY                  ;Get a keystroke.
  2017.                JC      F4_DONE
  2018.                CMP     AL,N_SCAN
  2019.                JZ      DO_PURGE
  2020.                CMP     AL,Y_SCAN               ;"Y" = archive.
  2021.                JNZ     NEXT_APPEND
  2022.                MOV     ARCHIVE_FLAG,1
  2023.  
  2024. DO_PURGE:      CALL    OPEN                    ;Open data file for reading.
  2025.                JBE     F4_DONE                 ;If doesn't exist, nothing to
  2026.                MOV     READ_HANDLE,AX          ; purge; else save handle.
  2027.  
  2028.                MOV     AX,8
  2029.                CALL    CALC_ADDR
  2030.                ADD     DI,50 * 2
  2031.                MOV     SI,OFFSET PURGING_MSG
  2032.                CALL    POP_WINDOW              ;Display purging window.
  2033.  
  2034.                CALL    OPEN                    ;Open data file for writing.
  2035.                JBE     PURGE_FAIL
  2036.                MOV     WRITE_HANDLE,AX
  2037.  
  2038.                MOV     SI,OFFSET SCH_ARC
  2039.                MOV     RECORD_SIZE,SIZE DATA_RECORD
  2040.                CMP     STATE,OFFSET APPOINTMENT
  2041.                JZ      ARCHIVE_NAME
  2042.                MOV     SI,OFFSET JOU_ARC
  2043.                MOV     RECORD_SIZE,JOURNAL_REC
  2044. ARCHIVE_NAME:  CALL    APPEND
  2045.  
  2046.                CMP     ARCHIVE_FLAG,1          ;Archive?
  2047.                JNZ     NEXT_PURGE
  2048.  
  2049.                CALL    OPEN                    ;If yes, open archive file.
  2050.                JA      SAVE_HANDLE2
  2051.                XOR     CX,CX
  2052.                MOV     AH,3CH                  ;If doesn't exist, create one.
  2053.                CALL    INT21_IO
  2054.                JBE     PURGE_FAIL
  2055. SAVE_HANDLE2:  MOV     ARCHIVE_HANDLE,AX
  2056.                MOV     BX,AX
  2057.                XOR     CX,CX
  2058.                XOR     DX,DX
  2059.                MOV     AX,4202H                ;Move to end of archive file
  2060.                CALL    INT21_IO                ; to append.
  2061.                JA      NEXT_PURGE
  2062.  
  2063. PURGE_FAIL:    CALL    CLOSE_HANDLES           ;Failure exit.
  2064.                CALL    FAILED
  2065.                JMP     F4_END
  2066.  
  2067.  
  2068. NEXT_PURGE:    MOV     CX,RECORD_SIZE
  2069.                MOV     BX,READ_HANDLE
  2070.                CALL    READ_RECORD             ;Read a record.
  2071.                JBE     PURGE_FAIL
  2072.                OR      AX,AX                   ;EOF?
  2073.                JZ      PURGE_DONE
  2074.                CMP     DATEONLY_FLAG,1         ;Purge everything < purge date.
  2075.                JZ      CK_THISDATE
  2076.                CMP     CX,YEAR_CAL             ;If no, year < purge date?
  2077.                JB      CK_ARCHIVE              ;If yes, purge.
  2078.                JA      WRITE_DATA              ;If above write data back.
  2079.                CMP     DX,DAY_MON_CAL          ;Else, day/month <= purge date?
  2080.                JBE     CK_ARCHIVE              ;Is yes, purge.
  2081.                JMP     SHORT WRITE_DATA        ;Else, write data back.
  2082.  
  2083. CK_THISDATE:   CMP     CX,YEAR_CAL             ;Purge date only.
  2084.                JNZ     WRITE_DATA
  2085.                CMP     DX,DAY_MON_CAL
  2086.                JZ      CK_ARCHIVE
  2087.  
  2088. WRITE_DATA:    MOV     DX,OFFSET DTA           ;Write data back to data file.
  2089.                MOV     CX,RECORD_SIZE
  2090.                MOV     BX,WRITE_HANDLE
  2091.                CALL    WRITE_RECORD
  2092.                JBE     PURGE_FAIL
  2093.                JMP     NEXT_PURGE
  2094.  
  2095. CK_ARCHIVE:    CMP     ARCHIVE_FLAG,1          ;Archive?
  2096.                JNZ     NEXT_PURGE
  2097.                CALL    ARCHIVE
  2098.                JBE     PURGE_FAIL
  2099.                JMP     NEXT_PURGE
  2100.  
  2101. PURGE_DONE:    MOV     BX,WRITE_HANDLE
  2102.                XOR     CX,CX                   ;Truncate data file to
  2103.                CALL    WRITE_RECORD            ; current pointer location.
  2104.                JBE     PURGE_FAIL
  2105.                CALL    CLOSE_HANDLES           ;Close all file handles.
  2106.                JMP     F4_END
  2107.  
  2108. ;----------------------------------------------;
  2109. CLOSE_HANDLES: MOV     BX,READ_HANDLE
  2110.                CALL    CLOSE_SAVE
  2111.                MOV     BX,WRITE_HANDLE
  2112.                CALL    CLOSE_SAVE
  2113.                MOV     BX,ARCHIVE_HANDLE
  2114.                CALL    CLOSE_SAVE
  2115.                RET
  2116.  
  2117. ;----------------------------------------------;
  2118. ARCHIVE:       MOV     BX,ARCHIVE_HANDLE
  2119.                MOV     DX,OFFSET DTA.DATE_ASCII
  2120.                MOV     CX,SIZE DATE_ASCII      ;Write date in ASCII.
  2121.                CALL    WRITE_RECORD
  2122.                JBE     ARCHIVE_END
  2123.                MOV     DTA,CR
  2124.                MOV     DTA + 1,LF
  2125.                CALL    WRITE_CRLF              ;Add Carriage return/linefeed.
  2126.                JBE     ARCHIVE_END
  2127.  
  2128.  
  2129.                CMP     STATE,OFFSET JOURNAL
  2130.                JNZ     APP_ARCHIVE
  2131.                JMP     SHORT DO_JOU_ARC
  2132.  
  2133.  
  2134. APP_ARCHIVE:   MOV     BP,APP_HEIGHT
  2135.                MOV     SI,OFFSET APP_START + 4
  2136.                MOV     DI,OFFSET DTA.DATA_TEXT
  2137. NEXT_ARCHIVE:  MOV     DX,SI
  2138.                MOV     CX,8
  2139.                CALL    WRITE_RECORD            ;Write times.
  2140.                JBE     ARCHIVE_END
  2141.                MOV     DX,DI
  2142.                MOV     CX,APP_LEN
  2143.                CALL    WRITE_RECORD            ;Write appointments.
  2144.                JBE     ARCHIVE_END
  2145.                ADD     SI,37
  2146.                ADD     DI,APP_LEN
  2147.                MOV     DX,SI
  2148.                MOV     CX,7
  2149.                CALL    WRITE_RECORD
  2150.                JBE     ARCHIVE_END
  2151.                MOV     DX,DI
  2152.                MOV     CX,APP_LEN
  2153.                CALL    WRITE_RECORD
  2154.                JBE     ARCHIVE_END
  2155.                CALL    WRITE_CRLF
  2156.                JBE     ARCHIVE_END
  2157.                ADD     SI,44
  2158.                ADD     DI,APP_LEN
  2159.                DEC     BP
  2160.                JNZ     NEXT_ARCHIVE
  2161.  
  2162.                MOV     BP,3
  2163.                MOV     SI,OFFSET DTA.NOTEPAD_TEXT
  2164. NEXT_NOTEPAD:  MOV     DX,SI
  2165.                MOV     CX,73
  2166.                CALL    WRITE_RECORD            ;Write Notepad.
  2167.                JBE     ARCHIVE_END
  2168.                CALL    WRITE_CRLF
  2169.                JBE     ARCHIVE_END
  2170.                ADD     SI,APP_WIDTH
  2171.                DEC     BP
  2172.                JNZ     NEXT_NOTEPAD
  2173.                CALL    WRITE_CRLF
  2174.  
  2175. ARCHIVE_DONE:  OR      AL,1                    ;Indicate successful.
  2176.  
  2177. ARCHIVE_END:   RET
  2178.  
  2179.  
  2180. DO_JOU_ARC:    MOV     BP,JOU_HEIGHT
  2181.                MOV     DX,OFFSET JOU_START + 3
  2182. NEXT_JOU_ARC:  MOV     CX,APP_WIDTH - 6
  2183.                CALL    WRITE_RECORD
  2184.                JBE     ARCHIVE_END
  2185.                PUSH    DX
  2186.                CALL    WRITE_CRLF
  2187.                POP     DX
  2188.                JBE     ARCHIVE_END
  2189.                ADD     DX,APP_WIDTH
  2190.                DEC     BP
  2191.                JNZ     NEXT_JOU_ARC
  2192.                CALL    WRITE_CRLF
  2193.                JMP     ARCHIVE_DONE
  2194.  
  2195.  
  2196. WRITE_CRLF:    MOV     DX,OFFSET DTA
  2197.                MOV     CX,2
  2198.                CALL    WRITE_RECORD
  2199.                RET
  2200.  
  2201. APPEND:        MOV     DI,PATH_END                 ;LINE 2159
  2202. NEXT_APPEND2:  LODSB
  2203.                STOSB
  2204.                OR      AL,AL
  2205.                JNZ     NEXT_APPEND2
  2206.                RET
  2207.  
  2208. ;**********************************************;
  2209. ;               J O U R N A L                  ;
  2210. ;**********************************************;
  2211.  
  2212. NUM_SIZE       EQU     10
  2213. TEXT_SIZE      EQU     50
  2214.  
  2215. JOU_FIELDS     STRUC
  2216. BUSINESS       DB      TEXT_SIZE DUP (?)
  2217. TAXI           DB      NUM_SIZE DUP (?)
  2218. AUTO_R         DB      NUM_SIZE DUP (?)
  2219. TRAIN          DB      NUM_SIZE DUP (?)
  2220. AUTO_P         DB      NUM_SIZE DUP (?)
  2221. AIRFARE        DB      NUM_SIZE DUP (?)
  2222. PARKING        DB      NUM_SIZE DUP (?)
  2223. TOLL           DB      NUM_SIZE DUP (?)
  2224. OTHER_TRAVEL   DB      NUM_SIZE DUP (?)
  2225.  
  2226. LODGING        DB      NUM_SIZE DUP (?)
  2227.  
  2228. BREAKFAST      DB      NUM_SIZE DUP (?)
  2229. LUNCH          DB      NUM_SIZE DUP (?)
  2230. DINNER         DB      NUM_SIZE DUP (?)
  2231. OTHER_MEALS    DB      NUM_SIZE DUP (?)
  2232.  
  2233. ENTERTAINMENT  DB      NUM_SIZE DUP (?)
  2234. PLACE          DB      TEXT_SIZE DUP (?)
  2235. NATURE         DB      TEXT_SIZE DUP (?)
  2236. PERSONS        DB      TEXT_SIZE DUP (?)
  2237. PURPOSE        DB      TEXT_SIZE DUP (?)
  2238.  
  2239. PHONE          DB      NUM_SIZE DUP (?)
  2240. OTHER          DB      NUM_SIZE DUP (?)
  2241.  
  2242. ADVANCE        DB      NUM_SIZE DUP (?)
  2243.  
  2244. PRE_PAID       DB      NUM_SIZE DUP (?)
  2245. JOU_FIELDS     ENDS
  2246.  
  2247. JOURNAL_REC    EQU     SIZE DATE_BINARY + SIZE DATE_ASCII + SIZE JOU_FIELDS
  2248.  
  2249. FIELDS STRUC
  2250. ACC_ROW        DB      ?
  2251. ACC_COL        DB      ?
  2252. ACC_LEN        DW      ?
  2253. FIELDS ENDS
  2254.  
  2255. JOU_ROW_HOME   EQU     4
  2256. JOU_COL_HOME   EQU     21
  2257. JOU_HOME       EQU     JOU_ROW_HOME SHL 8 + JOU_COL_HOME
  2258.  
  2259. JOU_CURSOR     DW      JOU_HOME
  2260. JOU_INDEX      DW      0
  2261.  
  2262. ACC_FIELDS     LABEL   BYTE
  2263. A_BUSINESS     FIELDS  < JOU_ROW_HOME - 4, JOU_COL_HOME, SIZE BUSINESS >
  2264. A_TAXI         FIELDS  < 2, 11, SIZE TAXI >
  2265. A_AUTO_R       FIELDS  < 2, 43, SIZE AUTO_R >
  2266. A_TRAIN        FIELDS  < 3, 16, SIZE TRAIN >
  2267. A_AUTO_P       FIELDS  < 3, 50, SIZE AUTO_P >
  2268. A_AIRFARE      FIELDS  < 4, 14, SIZE AIRFARE >
  2269. A_PARKING      FIELDS  < 4, 37, SIZE PARKING >
  2270. A_TOLL         FIELDS  < 5, 11, SIZE TOLL >
  2271. A_OTHER_TRAVEL FIELDS  < 5, 35, SIZE OTHER_TRAVEL >
  2272.  
  2273. A_LODGING      FIELDS  < 6, 12, SIZE LODGING >
  2274.  
  2275. A_BREAKFAST    FIELDS  < 8, 16, SIZE BREAKFAST >
  2276. A_LUNCH        FIELDS  < 8, 33, SIZE LUNCH >
  2277. A_DINNER       FIELDS  < 8, 51, SIZE DINNER >
  2278. A_OTHER_MEALS  FIELDS  < 8, 68, SIZE OTHER_MEALS >
  2279.  
  2280. A_ENTERTAIN    FIELDS  <10, 13, SIZE ENTERTAINMENT >
  2281. A_PLACE        FIELDS  <11, 12, SIZE PLACE >
  2282. A_NATURE       FIELDS  <12, 28, SIZE NATURE >
  2283. A_PERSONS      FIELDS  <13, 26, SIZE PERSONS >
  2284. A_PURPOSE      FIELDS  <14, 14, SIZE PURPOSE >
  2285.  
  2286. A_PHONE        FIELDS  <15, 18, SIZE PHONE >
  2287. A_OTHER        FIELDS  <16, 10, SIZE OTHER >
  2288.  
  2289. A_ADVANCE      FIELDS  <17, 12, SIZE ADVANCE >
  2290.  
  2291. A_PRE_PAID     FIELDS  <18, 26, SIZE PRE_PAID >
  2292.  
  2293. FIELDS_CNT     =  ($ - OFFSET ACC_FIELDS) / SIZE FIELDS
  2294.  
  2295. JOU_MENU       LABEL   BYTE
  2296. DB 2,B
  2297. DB " F2 Save  F3 Today  F4 Purge  F5 Report  F6 Clear  F7 Appointment   PgUp/Dn=Day ",3
  2298. JOU_REPORT     LABEL   BYTE
  2299. DB " ┌─────────────────────────────────────────────────┬──────────────────────────┐ ",3
  2300. DB " │      ",2,Y,"Journal",2,B," ■ PC Magazine ■ Michael J. Mefford │ ",2,Y,SPACE
  2301. JOU_DATE       LABEL   BYTE
  2302. DB                                                       "                ",7,14,2,B," │ ",3
  2303. DB " ╞═════════════════════════════════════════════════╧══════════════════════════╡ ",3
  2304. JOU_START      LABEL   BYTE
  2305. DB " │ BUSINESS PURPOSE:                                                          │ ",3
  2306. DB " │ TRAVEL: "
  2307. TRAVEL_ENTRY   LABEL   BYTE
  2308. DB            "                                                                   │ ",3
  2309. DB " │   Taxi:                  Auto (Rental):                                    │ ",3
  2310. DB " │   Train/Bus:             Auto (pers.)/mileage:                             │ ",3
  2311. DB " │   Airfare:               Parking:                                          │ ",3
  2312. DB " │   Toll:                  Other:                                            │ ",3
  2313. DB " │ LODGING:                                                                   │ ",3
  2314. DB " │ MEALS: "
  2315. MEALS_ENTRY    LABEL   BYTE
  2316. DB           "                                                                    │ ",3
  2317. DB " │   Breakfast:           Lunch:           Dinner:           Other:           │ ",3
  2318. DB " │ ENTERTAINMENT:                                                             │ ",3
  2319. DB " │   Amount:                                                                  │ ",3
  2320. DB " │   Place:                                                                   │ ",3
  2321. DB " │   Nature of expenditure:                                                   │ ",3
  2322. DB " │   Persons entertained:                                                     │ ",3
  2323. DB " │   Purpose:                                                                 │ ",3
  2324. DB " │ TELEPHONE/FAX:                                                             │ ",3
  2325. DB " │ OTHER:                                                                     │ ",3
  2326. DB " │ ADVANCE:                                                                   │ ",3
  2327. DB " │"
  2328. COMPANY_PAID   LABEL   BYTE
  2329. DB   " COMPANY PAID EXPENSES: "
  2330. COMPANY_LEN    EQU     $ - COMPANY_PAID
  2331. DB                           "                                                    │ ",3
  2332. JOU_HEIGHT EQU ($ - JOU_START) / APP_WIDTH
  2333. DB " │ "
  2334. TOTAL_ENTRY    LABEL   BYTE
  2335. DB    "                                                                           │ ",3
  2336. DB " └────────────────────────────────────────────────────────────────────────────┘ ",3,-1
  2337.  
  2338.  
  2339. REPORT_MSG     DB 2,H,"╔",0,41,               "═",              "╗",3
  2340.                DB     "║ Journal Report Date: ",2,P
  2341. REPORT_DATE    DB                            "                   ",2,H,"║",1
  2342.                DB     "║   PgUp/Dn to change Date; F3 = Today    ║",1
  2343.                DB     "║   Report up to and including Date       ║",1
  2344.                DB     "║     F6 Total only                       ║",1
  2345.                DB     "║     F7 Complete Report - LPT1           ║",1
  2346.                DB     "║     F8 Complete Report - LPT2           ║",1
  2347.                DB     "║     F9 Complete Report - File           ║",1
  2348.                DB     "║        Esc to Cancel                    ║",1
  2349.                DB     "╚",0,41,               "═",              "╝",1,4,43
  2350.  
  2351.  
  2352. FILENAME_MSG   DB 2,H,"╔",    0,23,"═",       "╗",3
  2353.                DB     "║ "
  2354. FILENAME       DB       "                     "
  2355. FILENAME_LEN   EQU     $
  2356.                DB                            " ║",1
  2357.                DB     "╚",    0,23,"═",       "╝",1,4,25
  2358.  
  2359. GRAND_MSG      DB  2,H,"╔",         0,28,"═",           "╗",3
  2360.                DB      "║"
  2361. GRAND_AMOUNT   DB       " GRAND TOTAL: "
  2362. GRAND_VALUE    DB                     "              "
  2363. GRAND_LEN      EQU     $ - GRAND_VALUE
  2364. GRAND_LEN2     EQU     $ - GRAND_AMOUNT
  2365.                DB                                   "║",1
  2366.                DB      "║ Press any key to continue. ║",1
  2367.                DB      "╚",         0,28,"═",           "╝",1,4,30
  2368.  
  2369.  
  2370. JTABLE         DB  3CH,        3DH,    3EH,    3FH,        40H,        59H
  2371.                DB  63H,        4BH,    4DH,    48H,        50H,        47H
  2372.                DB  4FH,        49H,    51H,    84H,        76H,        77H
  2373.                DB  75H,        73H,    74H,    0FH,        53H
  2374. JTABLE_LEN     EQU     $ - JTABLE
  2375.                DW  SAVE,       ATODAY, PPURGE, REPORT,     JCLEAR,     JSHIFT_CLEAR
  2376.                DW  JCTRL_CLEAR,JLEFT,  JRIGHT, JSHIFT_TAB, NEXT_FIELD, JHOME
  2377.                DW  JEND,       APGUP,  APGDN,  ACTRLPGUP,  ACTRLPGDN,  JCTRLHOME
  2378.                DW  JCTRLEND,   JHOME,  JEND,   JSHIFT_TAB, JDEL
  2379.  
  2380.  
  2381. JOURNAL:       MOV     SI,OFFSET JOU_DAT
  2382.                CALL    APPEND
  2383.  
  2384.                CALL    CK_DATE
  2385.                MOV     SI,OFFSET JOU_MENU
  2386.                CALL    POP_MENU
  2387.  
  2388. NEXT_JOURNAL:  MOV     DX,JOU_CURSOR
  2389.                CALL    SET_CURSOR
  2390.                CALL    GETKEY
  2391.                CMP     EXIT_FLAG,1
  2392.                JZ      JOURNAL_END
  2393.  
  2394.                CMP     AL,SHIFT_F7_SCAN
  2395.                JNZ     CK_JOU_F7
  2396.                CALL    PERMANENT
  2397.                MOV     STATE,OFFSET CALENDAR
  2398.                JMP     SHORT JOURNAL_END
  2399.  
  2400. CK_JOU_F7:     CMP     AL,F7_SCAN
  2401.                JNZ     CK_JOU_ESC
  2402.                CALL    PERMANENT
  2403.                MOV     STATE,OFFSET APPOINTMENT
  2404.                JMP     SHORT JOURNAL_END
  2405.  
  2406. CK_JOU_ESC:    CMP     AL,ESC_SCAN             ;Back to calendar if Esc.
  2407.                JNZ     JOU_DISPATCH
  2408.                CALL    PERMANENT
  2409.                MOV     STATE,OFFSET CALENDAR
  2410.                JMP     SHORT JOURNAL_END
  2411. JOU_DISPATCH:  MOV     BP,JOU_INDEX
  2412.                CALL    CALC_JOU_ADDR           ;Get cursor bounds.
  2413.                OR      AH,AH                   ;Extended scan code?
  2414.  
  2415.  
  2416.                JZ      GOT_JDISPATCH
  2417.                CALL    CK_JENTRY
  2418.                JMP     NEXT_JOURNAL
  2419.  
  2420. GOT_JDISPATCH: MOV     DI,OFFSET JTABLE
  2421.                MOV     CX,JTABLE_LEN
  2422.                CALL    DISPATCH
  2423.                CMP     EXIT_FLAG,1
  2424.                JNZ     JOURNAL
  2425.                CALL    PERMANENT
  2426.  
  2427. JOURNAL_END:   RET
  2428.  
  2429. ;----------------------------------------------;
  2430. ; INPUT:  BP=JOU_INDEX; DX=cursor position
  2431. ; OUTPUT: BH=column end; BL=column home; CL=row home; SI-> storage
  2432.  
  2433. CALC_JOU_ADDR: PUSH    AX
  2434.                MOV     AX,BP
  2435.                MOV     AH,SIZE FIELDS
  2436.                MUL     AH
  2437.                MOV     SI,AX
  2438.                ADD     SI,OFFSET ACC_FIELDS
  2439.                LODSB                           ;Home row
  2440.                MOV     CL,AL
  2441.                MOV     CH,APP_WIDTH
  2442.                MUL     CH
  2443.                ADD     AX,OFFSET JOU_START
  2444.                MOV     DI,AX
  2445.                MOV     AX,DX
  2446.                XOR     AH,AH
  2447.                ADD     DI,AX
  2448.  
  2449.                LODSB                           ;Home column
  2450.                MOV     BL,AL
  2451.  
  2452.                LODSW
  2453.                MOV     BH,BL
  2454.                ADD     BH,AL
  2455.                DEC     BH                      ;End column
  2456.                MOV     SI,DI
  2457.                POP     AX
  2458.                RET
  2459.  
  2460. ;----------------------------------------------;
  2461. ; INPUT: BP=JOU_INDEX; DX=Cursor; BH=column end; BL=column home; SI-> storage
  2462.  
  2463. JSHIFT_TAB:    MOV     CX,-1
  2464.                JMP     SHORT NEXT_FIELD2
  2465.  
  2466. CK_JENTRY:     XCHG    AH,AL
  2467.                CMP     AL,TAB
  2468.                JZ      NEXT_FIELD
  2469.                CMP     AL,CR
  2470.                JNZ     CK_JBACKSPACE
  2471.                MOV     AH,2
  2472.                INT     16H
  2473.                TEST    AL,1 OR 2
  2474.                JNZ     JSHIFT_TAB
  2475.  
  2476. NEXT_FIELD:    MOV     CX,1
  2477. NEXT_FIELD2:   MOV     AX,FIELDS_CNT - 1
  2478.                ADD     BP,CX
  2479.                JNS     CK_JHIGH
  2480.                MOV     BP,AX
  2481. CK_JHIGH:      CMP     BP,AX
  2482.                JBE     GET_FIELD
  2483.                XOR     BP,BP
  2484. GET_FIELD:     MOV     JOU_INDEX,BP
  2485.                CALL    CALC_JOU_ADDR
  2486.                MOV     DH,CL
  2487.                ADD     DH,4
  2488.                MOV     DL,BL
  2489.                JMP     SHORT JOU_UPDATE
  2490.  
  2491. CK_JBACKSPACE: CMP     AL,8
  2492.                JNZ     JOU_ASCII
  2493.                CMP     DL,BL
  2494.                JZ      JENTRY_END
  2495.                DEC     SI
  2496.                DEC     DL
  2497.                MOV     JOU_CURSOR,DX
  2498.                CALL    JDEL
  2499.                JMP     SHORT JENTRY_END
  2500.  
  2501. JOU_ASCII:     CMP     AL,SPACE
  2502.                JB      JENTRY_END
  2503.                OR      BP,BP
  2504.                JZ      CK_ROOM
  2505.                CMP     BP,15
  2506.                JB      CK_NUMERIC
  2507.                CMP     BP,18
  2508.                JBE     CK_ROOM
  2509.  
  2510. CK_NUMERIC:    CMP     AL,"$"
  2511.                JZ      CK_ROOM
  2512.                CMP     AL,"."
  2513.                JZ      CK_ROOM
  2514.                CMP     AL,"0"
  2515.                JB      ILLEGAL
  2516.                CMP     AL,"9"
  2517.                JBE     CK_ROOM
  2518.  
  2519. ILLEGAL:       CALL    BEEP
  2520.                JMP     SHORT JENTRY_END
  2521.  
  2522. CK_ROOM:       INC     DL
  2523.                SUB     BH,DL
  2524.                JC      JENTRY_END
  2525.                JZ      STORE_JOU
  2526.                MOV     CL,BH
  2527.                XOR     CH,CH
  2528.                ADD     SI,CX
  2529.                MOV     DI,SI
  2530.                DEC     SI
  2531.                STD
  2532.                REP     MOVSB
  2533.                CLD
  2534.                INC     SI
  2535. STORE_JOU:     MOV     [SI],AL
  2536.  
  2537. JOU_CHANGE:    MOV     MODIFY_FLAG,1
  2538. JOU_UPDATE:    MOV     JOU_CURSOR,DX
  2539.  
  2540.                MOV     SI,OFFSET JOU_START
  2541.                CALL    DISPLAY_LINE
  2542.  
  2543. JENTRY_END:    RET
  2544.  
  2545. ;----------------------------------------------;
  2546. JCLEAR:        CALL    CLEAR_IT
  2547.                JMP     JOU_CHANGE
  2548.  
  2549. CLEAR_IT:      CALL    CALC_JOU_ADDR
  2550.                MOV     DL,BL
  2551.                CALL    CALC_JOU_ADDR
  2552.                SUB     BH,BL
  2553.                MOV     CL,BH
  2554.                XOR     CH,CH
  2555.                MOV     AL,SPACE
  2556.                REP     STOSB
  2557.                RET
  2558.  
  2559. JSHIFT_CLEAR:
  2560. JCTRL_CLEAR:   MOV     BP,FIELDS_CNT
  2561. NEXT_CLEAR:    DEC     BP
  2562.                CALL    CLEAR_IT
  2563.                OR      BP,BP
  2564.                JNZ     NEXT_CLEAR
  2565.                MOV     DH,JOU_ROW_HOME
  2566.                MOV     JOU_INDEX,BP
  2567.                JMP     JOU_CHANGE
  2568.  
  2569. JHOME:         CMP     DL,BL                   ;Beginning of field unless
  2570.                MOV     DL,BL                   ; already there, then go
  2571.                JNZ     JOU_UPDATE              ; to section home.
  2572.  
  2573. JCTRLHOME:     MOV     DX,JOU_HOME
  2574.                XOR     BP,BP
  2575.                MOV     JOU_INDEX,BP
  2576.                JMP     JOU_UPDATE
  2577.  
  2578. JEND:          CALL    GET_WORD
  2579.                CMP     DI,SI
  2580.                JZ      JCTRLEND
  2581.                MOV     BX,DI
  2582.                MOV     CX,SI
  2583.                SUB     BX,CX
  2584.                ADD     DL,BL
  2585.                JMP     JOU_UPDATE
  2586.  
  2587. JCTRLEND:      MOV     DH,A_PRE_PAID.ACC_ROW
  2588.                ADD     DH,4
  2589.                MOV     DL,A_PRE_PAID.ACC_COL
  2590.                ADD     DL,SIZE PRE_PAID - 1
  2591.                MOV     BP,FIELDS_CNT - 1
  2592.                MOV     JOU_INDEX,BP
  2593.                JMP     JOU_UPDATE
  2594.  
  2595. JLEFT:         DEC     DL
  2596.                CMP     DL,BL                   ;Left one space unless
  2597.                JAE     JOU_UPDATE
  2598.                JMP     JENTRY_END
  2599.  
  2600. JRIGHT:        INC     DL                      ;Right on space unless
  2601.                CMP     DL,BH                   ; already column end.
  2602.                JBE     JOU_UPDATE
  2603.                JMP     JENTRY_END
  2604.  
  2605. JDEL:          SUB     BH,DL                   ;Ignore if in last column.
  2606.                MOV     CL,BH
  2607.                XOR     CH,CH
  2608.                JCXZ    JDEL_END
  2609.                MOV     DI,SI
  2610.                INC     SI
  2611.                REP     MOVSB                   ;Else, move everything to right
  2612.                MOV     SI,OFFSET JOU_START
  2613.                CALL    DISPLAY_LINE            ; of cursor left one space.
  2614.                MOV     MODIFY_FLAG,1
  2615. JDEL_END:      RET
  2616.  
  2617. ;----------------------------------------------;
  2618. STORE_JOURNAL: PUSH    BX
  2619.                PUSH    BP
  2620.                MOV     SI,OFFSET DTA.DATA_TEXT
  2621.                MOV     BP,FIELDS_CNT
  2622.                MOV     BX,OFFSET ACC_FIELDS
  2623.                MOV     DL,APP_WIDTH
  2624.  
  2625. NEXT_STORE_JOU:MOV     AL,[BX]
  2626.                INC     BX
  2627.                MUL     DL
  2628.                MOV     DI,AX
  2629.                MOV     AL,[BX]
  2630.                INC     BX
  2631.                XOR     AH,AH
  2632.                ADD     DI,AX
  2633.                ADD     DI,OFFSET JOU_START
  2634.  
  2635.                MOV     CX,[BX]
  2636.                INC     BX
  2637.                INC     BX
  2638.                REP     MOVSB
  2639.  
  2640.                DEC     BP
  2641.                JNZ     NEXT_STORE_JOU
  2642.                POP     BP
  2643.                POP     BX
  2644.                RET
  2645.  
  2646. ;----------------------------------------------;
  2647. COMPLETE_FLAG  DB      ?                       ; =1 if complete report.
  2648.  
  2649. REPORT_SORT    STRUC
  2650. DATE           DD      ?
  2651. RECORD_NO      DW      ?
  2652. REPORT_SORT    ENDS
  2653.  
  2654. REPORT_MAX     EQU     365
  2655. REPORT_INDEX   REPORT_SORT REPORT_MAX DUP (<>)
  2656. REPORT_INDEX_END  EQU  $
  2657.  
  2658. VARS           LABEL   BYTE
  2659. J_TRAVEL       DW      2 DUP (?)
  2660. J_MEALS        DW      2 DUP (?)
  2661. TOTAL          DW      2 DUP (?)
  2662. VARS_LEN       EQU     $ - VARS
  2663. T_PRE_PAID     DW      2 DUP (?)
  2664. GRAND_TOTAL    DW      2 DUP (?)
  2665.  
  2666. FF_FLAG        DB      0                       ;Toggle for 2 reports/page.
  2667. PRINTER_FLAG   DB      0                       ; 1= output to printer.
  2668.  
  2669. REPORT:        CALL    PERMANENT
  2670.                MOV     SI,OFFSET JOU_MENU
  2671.                CALL    POP_MENU
  2672.  
  2673.                PUSH    YEAR_CAL                ;Preserve calendar variables.
  2674.                PUSH    DAY_MON_CAL
  2675.                PUSH    YEAR_CUR
  2676.                PUSH    DAY_MON_CUR
  2677.                CALL    HIDE_CURSOR
  2678.  
  2679. NEXT_REPORT:   CALL    FIRSTDAY                ;Store purge date in window.
  2680.                MOV     AX,1
  2681.                CALL    CALC_ADDR
  2682.                ADD     DI,9 * 2
  2683.                MOV     SI,OFFSET REPORT_MSG
  2684.                CALL    POP_WINDOW              ;Display purge window.
  2685.                CALL    GETKEY                  ;Get a keystroke.
  2686.                JC      REPORT_DONE             ;If Esc, exit.
  2687.  
  2688.                MOV     COMPLETE_FLAG,0
  2689.                CMP     AL,F6_SCAN              ;Is it F6?
  2690.                JZ      REPORTS
  2691.  
  2692.                MOV     COMPLETE_FLAG,1
  2693.                MOV     PRINTER,0
  2694.                MOV     FF_FLAG,3
  2695.                MOV     PRINTER_FLAG,1
  2696.  
  2697.                CMP     AL,F7_SCAN              ;Is it F7.
  2698.                JZ      PRINTER_OUT
  2699.                MOV     PRINTER,1
  2700.                CMP     AL,F8_SCAN
  2701.                JNZ     CK_FILE_OUT
  2702.  
  2703. PRINTER_OUT:   CALL    PRINTER_SETUP
  2704.                JC      REPORT_DONE
  2705.                JMP     SHORT REPORTS
  2706.  
  2707. CK_FILE_OUT:   CMP     AL,F9_SCAN
  2708.                JNZ     R_DISPATCH
  2709.                MOV     PRINTER_FLAG,0
  2710.                CALL    GET_FILENAME
  2711.                JC      REPORT_DONE
  2712.                JMP     SHORT REPORTS
  2713.  
  2714. R_DISPATCH:    MOV     DI,OFFSET PTABLE
  2715.                MOV     CX,PTABLE_LEN
  2716.                CALL    DISPATCH
  2717.                CMP     EXIT_FLAG,1
  2718.                JNZ     NEXT_REPORT
  2719.  
  2720. REPORT_DONE:   POP     DAY_MON_CUR             ;Restore calendar variables.
  2721.                POP     YEAR_CUR
  2722.                POP     DAY_MON_CAL
  2723.                POP     YEAR_CAL
  2724.                CALL    CLS_TRA_MEALS
  2725.                MOV     REREAD_FLAG,1
  2726.                CALL    FLUSH_KEY
  2727.                RET
  2728.  
  2729. ;----------------------;
  2730. REPORTS:       CALL    OPEN
  2731.                MOV     READ_HANDLE,BX
  2732.                JBE     LILLY_ERR2
  2733.                MOV     DI,OFFSET REPORT_INDEX
  2734.                MOV     SI,-1                   ;Entry no.
  2735.  
  2736. NEXT_READ_REP: MOV     CX,JOURNAL_REC
  2737.                CALL    READ_RECORD
  2738.                JBE     LILLY_ERR2
  2739.                OR      AX,AX
  2740.                JZ      SORT_REPORTS
  2741.                INC     SI
  2742.  
  2743.                CMP     CX,YEAR_CAL
  2744.                JB      DO_INDEX
  2745.                JA      NEXT_READ_REP
  2746.                CMP     DX,DAY_MON_CAL
  2747.                JA      NEXT_READ_REP
  2748.  
  2749. DO_INDEX:      MOV     AX,CX
  2750.                STOSW
  2751.                MOV     AX,DX
  2752.                STOSW
  2753.                MOV     AX,SI
  2754.                STOSW
  2755.                CMP     DI,OFFSET REPORT_INDEX_END
  2756.                JB      NEXT_READ_REP
  2757.                CALL    BEEP
  2758.                JMP     REPORTS_DONE
  2759.  
  2760. SORT_REPORTS:  MOV     AX,-1
  2761.                STOSW
  2762.                OR      SI,SI                   ;If less than 2 records,
  2763.                JZ      SHORT READ_REPORTS      ; don't sort.
  2764.  
  2765.                CALL    SORT
  2766.  
  2767. ;----------------------;
  2768.  
  2769. READ_REPORTS:  CALL    ZERO_VARS
  2770.                XOR     BP,BP                   ; REPORT_INDEX
  2771. NEXT_REPORTS:  MOV     AH,1
  2772.                INT     16H
  2773.                JZ      NEXT_REPORTS2
  2774.                CALL    GETKEY
  2775.                CMP     AL,ESC_SCAN
  2776.                JZ      TOTAL_REPORT
  2777.  
  2778. NEXT_REPORTS2: CMP     WORD PTR REPORT_INDEX.DATE[BP],-1
  2779.                JZ      TOTAL_REPORT
  2780.                MOV     AX,REPORT_INDEX.RECORD_NO[BP]
  2781.                ADD     BP,SIZE REPORT_SORT
  2782.                MOV     DX,JOURNAL_REC
  2783.                MUL     DX
  2784.                MOV     CX,DX
  2785.                MOV     DX,AX
  2786.                MOV     BX,READ_HANDLE
  2787.                MOV     AX,4200H
  2788.                CALL    INT21_IO
  2789. LILLY_ERR2:    JBE     REPORTS_DONE
  2790.  
  2791.                MOV     CX,JOURNAL_REC
  2792.                CALL    READ_RECORD
  2793.                JBE     REPORTS_DONE
  2794.  
  2795.                CALL    ADD_FIELDS
  2796.  
  2797.                CMP     COMPLETE_FLAG,1
  2798.                JNZ     NEXT_REPORTS
  2799.  
  2800.                CALL    SUB_REPORT
  2801.                JC      REPORTS_DONE
  2802.                JMP     NEXT_REPORTS
  2803.  
  2804. TOTAL_REPORT:  CALL    DO_TOTAL
  2805.  
  2806. REPORTS_DONE:  MOV     BX,READ_HANDLE
  2807.                MOV     AH,3EH
  2808.                CALL    INT21_IO
  2809.                CMP     PRINTER_FLAG,1
  2810.                JZ      REPORTS_END
  2811.                MOV     BX,OUTPUT_HANDLE
  2812.                MOV     AH,3EH
  2813.                CALL    INT21_IO
  2814. REPORTS_END:   CALL    PPURGE
  2815.                JMP     REPORT_DONE
  2816.  
  2817. ;----------------------;
  2818.  
  2819. ZERO_VARS:     MOV     T_PRE_PAID[0],0
  2820.                MOV     T_PRE_PAID[2],0
  2821.                MOV     GRAND_TOTAL[0],0
  2822.                MOV     GRAND_TOTAL[2],0
  2823.                RET
  2824.  
  2825. ;----------------------;
  2826. ; OUTPUT: CF=1 if abort.
  2827.  
  2828. FILE_HOME      EQU     19
  2829. FILE_CURSOR    LABEL   WORD
  2830. FILE_COL       DB      FILE_HOME
  2831.                DB      14
  2832.  
  2833. OUTPUT_HANDLE  DW      ?
  2834.  
  2835. GET_FILENAME:  MOV     AX,13
  2836.                CALL    CALC_ADDR
  2837.                ADD     DI,17 * 2
  2838.                MOV     SI,OFFSET FILENAME_MSG
  2839.                CALL    POP_WINDOW
  2840.  
  2841.                MOV     DX,FILE_CURSOR
  2842.                CALL    SET_CURSOR
  2843.                XOR     DH,DH
  2844.                ADD     DX,OFFSET FILENAME - FILE_HOME
  2845.                MOV     DI,DX
  2846.                CALL    GETKEY
  2847.                JC      FILENAME_END
  2848.                XCHG    AH,AL
  2849.                OR      AH,AH
  2850.                JZ      GET_FILENAME
  2851.                CMP     AL,CR
  2852.                JZ      GOT_FILENAME
  2853.                CMP     AL,8
  2854.                JNZ     CK_FILE_ASCII
  2855.                CMP     DI,OFFSET FILENAME
  2856.                JZ      GET_FILENAME
  2857.                DEC     FILE_COL
  2858.                MOV     BYTE PTR [DI-1],SPACE
  2859.                JMP     GET_FILENAME
  2860.  
  2861. CK_FILE_ASCII: CMP     AL,SPACE
  2862.                JB      GET_FILENAME
  2863.                CMP     DI,OFFSET FILENAME_LEN
  2864.                JZ      GET_FILENAME
  2865.                STOSB
  2866.                INC     FILE_COL
  2867.                JMP     GET_FILENAME
  2868.  
  2869. FILENAME_END:  RET
  2870.  
  2871. GOT_FILENAME:  XOR     AL,AL
  2872.                STOSB
  2873.                MOV     DX,OFFSET FILENAME
  2874.                MOV     AX,3D01H
  2875.                CALL    INT21_IO
  2876.                JBE     CREATE_FILE
  2877.                MOV     BX,AX
  2878.                MOV     OUTPUT_HANDLE,AX
  2879.                XOR     CX,CX
  2880.                XOR     DX,DX
  2881.                MOV     AX,4202H
  2882.                CALL    INT21_IO
  2883.                JMP     SHORT FILENAME_OK
  2884.  
  2885. CREATE_FILE:   XOR     CX,CX
  2886.                MOV     AH,3CH
  2887.                CALL    INT21_IO
  2888.                MOV     OUTPUT_HANDLE,AX
  2889.                JA      FILENAME_OK
  2890.                MOV     BYTE PTR [DI-1],SPACE
  2891.                CALL    BEEP
  2892.                STC
  2893.                JMP     FILENAME_END
  2894.  
  2895. FILENAME_OK:   CLC
  2896.                MOV     BYTE PTR [DI-1],SPACE
  2897.                JMP     FILENAME_END
  2898.  
  2899. ;----------------------;
  2900.  
  2901. ADD_FIELDS:    MOV     DI,OFFSET VARS
  2902.                MOV     CX,VARS_LEN / 2
  2903.                XOR     AX,AX
  2904.                REP     STOSW                   ;Zero out vars. except GRAND_TOTAL
  2905.                                                ; and PRE_PAID
  2906.                MOV     SI,OFFSET DTA.DATA_TEXT.TAXI
  2907.                MOV     CX,8                    ;Eight travel entries.
  2908. NEXT_TRAVEL:   PUSH    CX
  2909.                CALL    ACCUMULATE
  2910.                ADD     J_TRAVEL[0],AX
  2911.                ADC     J_TRAVEL[2],DX
  2912.                POP     CX
  2913.                LOOP    NEXT_TRAVEL
  2914.  
  2915.                CALL    ACCUMULATE              ;Lodging.
  2916.                ADD     TOTAL[0],AX
  2917.                ADC     TOTAL[2],DX
  2918.  
  2919.                MOV     CX,4                    ;Four meal entries.
  2920. NEXT_MEAL:     PUSH    CX
  2921.                CALL    ACCUMULATE
  2922.                ADD     J_MEALS[0],AX
  2923.                ADC     J_MEALS[2],DX
  2924.                POP     CX
  2925.                LOOP    NEXT_MEAL
  2926.  
  2927.                CALL    ACCUMULATE              ;Entertainment.
  2928.                ADD     TOTAL[0],AX
  2929.                ADC     TOTAL[2],DX
  2930.  
  2931.                ADD     SI,SIZE PLACE + SIZE NATURE + SIZE PERSONS + SIZE PURPOSE
  2932.                CALL    ACCUMULATE              ;Telephone.
  2933.                ADD     TOTAL[0],AX
  2934.                ADC     TOTAL[2],DX
  2935.  
  2936.                CALL    ACCUMULATE              ;Other.
  2937.                ADD     TOTAL[0],AX
  2938.                ADC     TOTAL[2],DX
  2939.  
  2940.                CALL    ACCUMULATE              ;Advance.
  2941.                SUB     TOTAL[0],AX
  2942.                SBB     TOTAL[2],DX
  2943.  
  2944.                CALL    ACCUMULATE              ;Pre-paid.
  2945.                ADD     T_PRE_PAID[0],AX
  2946.                ADC     T_PRE_PAID[2],DX
  2947.  
  2948.                MOV     AX,J_TRAVEL[0]      ;Travel total.
  2949.                MOV     DX,J_TRAVEL[2]
  2950.                ADD     TOTAL[0],AX
  2951.                ADC     TOTAL[2],DX
  2952.  
  2953.                MOV     AX,J_MEALS[0]       ;Meals total.
  2954.                MOV     DX,J_MEALS[2]
  2955.                ADD     TOTAL[0],AX
  2956.                ADC     TOTAL[2],DX
  2957.  
  2958.                MOV     AX,TOTAL[0]         ;Grand total.
  2959.                MOV     DX,TOTAL[2]
  2960.                ADD     GRAND_TOTAL[0],AX
  2961.                ADC     GRAND_TOTAL[2],DX
  2962.  
  2963.                RET
  2964.  
  2965. ;----------------------;
  2966. ;OUTPUT: CF = 1 if abort.
  2967.  
  2968. IBM_FLAG       DB      0                       ; If 1, use line drawing chars.
  2969. IBM_CHARS      DB      "╞╡│╪┬─╤═╧■┌"
  2970. EPSON_CHARS    DB      "||||--===*+"           ;Replacements for line chars.
  2971. CHARS_LEN      EQU     $ - EPSON_CHARS
  2972.  
  2973.  
  2974. TOTAL_MSG      DB      "TOTAL: "
  2975. TOTAL_MSG_LEN  EQU     $ - TOTAL_MSG
  2976.  
  2977. SUB_REPORT:    CALL    CLS_TRA_MEALS
  2978.                CALL    STORE_JOURNAL
  2979.                MOV     SI,OFFSET DTA.DATE_ASCII
  2980.                MOV     DI,OFFSET JOU_DATE
  2981.                MOV     CX,SIZE DATE_ASCII
  2982.                REP     MOVSB
  2983.                MOV     AL,SPACE
  2984.                MOV     CX,4
  2985.                REP     STOSB                   ;Space out day of week.
  2986.  
  2987.                MOV     AX,J_TRAVEL[0]
  2988.                MOV     DX,J_TRAVEL[2]
  2989.                MOV     DI,OFFSET TRAVEL_ENTRY
  2990.                CALL    AMOUNT_ASCII
  2991.                MOV     AX,J_MEALS[0]
  2992.                MOV     DX,J_TRAVEL[2]
  2993.                MOV     DI,OFFSET MEALS_ENTRY
  2994.                CALL    AMOUNT_ASCII
  2995.                MOV     SI,OFFSET TOTAL_MSG
  2996.                MOV     DI,OFFSET TOTAL_ENTRY
  2997.                MOV     CX,TOTAL_MSG_LEN
  2998.                REP     MOVSB
  2999.                MOV     AX,TOTAL[0]
  3000.                MOV     DX,TOTAL[2]
  3001.                CALL    AMOUNT_ASCII
  3002.  
  3003.                MOV     SI,OFFSET JOU_REPORT
  3004.                MOV     DI,OFFSET DTA
  3005. NEXT_FORMAT:   LODSB
  3006.                CMP     AL,-1
  3007.                JZ      FORMAT_DONE
  3008.                CMP     AL,7
  3009.                JNZ     CK_EOL
  3010.                LODSB
  3011.                SHR     AL,1
  3012.                MOV     CL,AL
  3013.                XOR     CH,CH
  3014.                MOV     AL,SPACE
  3015.                REP     STOSB
  3016.                JMP     NEXT_FORMAT
  3017.  
  3018. CK_EOL:        CMP     AL,3
  3019.                JZ      FORMAT_CRLF
  3020.                CMP     AL,SPACE
  3021.                JB      NEXT_FORMAT
  3022.                CALL    CK_IBM
  3023.                STOSB
  3024.                JMP     NEXT_FORMAT
  3025.  
  3026. FORMAT_CRLF:   CALL    STORE_CRLF
  3027.                JMP     NEXT_FORMAT
  3028. FORMAT_DONE:   CALL    STORE_CRLF
  3029.                SUB     DI,OFFSET DTA
  3030.                MOV     CX,DI
  3031.  
  3032.                CMP     PRINTER_FLAG,1
  3033.                JZ      SUB_PRINTER
  3034.  
  3035. OUTPUT2:       MOV     BX,OUTPUT_HANDLE
  3036.                MOV     DX,OFFSET DTA
  3037.                MOV     AH,40H
  3038.                CALL    INT21_IO
  3039.                JMP     SHORT SUB_REPORT_END
  3040.  
  3041. ;----------------------;
  3042.  
  3043. SUB_PRINTER:   MOV     DX,PRINTER
  3044.                DEC     FF_FLAG
  3045.                JNZ     PRINT_REPORT
  3046.                MOV     FF_FLAG,2
  3047.                MOV     AL,FF
  3048.                CALL    PRINT_IT
  3049.                JC      SUB_REPORT_END
  3050.  
  3051. PRINT_REPORT:  MOV     SI,OFFSET DTA
  3052. NEXT_PR_REPORT:CALL    PRINT_A_CHAR
  3053.                JC      SUB_REPORT_END
  3054.                LOOP    NEXT_PR_REPORT
  3055.  
  3056. SUB_REPORT_END:RET
  3057.  
  3058.  
  3059. ;----------------------;
  3060. CLS_TRA_MEALS: MOV     AX,SPACE SHL 8 + SPACE
  3061.                MOV     DI,OFFSET TRAVEL_ENTRY
  3062.                MOV     CX,NUM_SIZE
  3063.                REP     STOSW
  3064.                MOV     DI,OFFSET MEALS_ENTRY
  3065.                MOV     CX,NUM_SIZE
  3066.                REP     STOSW
  3067.                MOV     DI,OFFSET TOTAL_ENTRY
  3068.                MOV     CX,NUM_SIZE
  3069.                REP     STOSW
  3070.                MOV     DI,OFFSET GRAND_VALUE
  3071.                MOV     CX,GRAND_LEN
  3072.                REP     STOSB
  3073.                RET
  3074.  
  3075. ;----------------------;
  3076. DO_TOTAL:      MOV     AX,GRAND_TOTAL[0]
  3077.                MOV     DX,GRAND_TOTAL[2]
  3078.                MOV     DI,OFFSET GRAND_VALUE
  3079.                CALL    AMOUNT_ASCII
  3080.  
  3081.                CMP     COMPLETE_FLAG,1
  3082.                JZ      DO_COMPLETE
  3083.  
  3084.                MOV     AX,13
  3085.                CALL    CALC_ADDR
  3086.                ADD     DI,17 * 2
  3087.                MOV     SI,OFFSET GRAND_MSG
  3088.                CALL    POP_WINDOW
  3089.  
  3090.                CALL    FLUSH_KEY
  3091.                XOR     AH,AH
  3092.                INT     16H
  3093.                JMP     SHORT DO_TOTAL_END
  3094.  
  3095. DO_COMPLETE:   MOV     DI,OFFSET DTA
  3096.                MOV     SI,OFFSET COMPANY_PAID
  3097.                MOV     CX,COMPANY_LEN
  3098.                REP     MOVSB
  3099.  
  3100.                MOV     AX,T_PRE_PAID[0]
  3101.                MOV     DX,T_PRE_PAID[2]
  3102.                CALL    AMOUNT_ASCII
  3103.                CALL    STORE_CRLF
  3104.  
  3105.                MOV     SI,OFFSET GRAND_AMOUNT
  3106.                MOV     CX,GRAND_LEN2
  3107.                REP     MOVSB
  3108.                CALL    STORE_CRLF
  3109.                CALL    STORE_CRLF
  3110.  
  3111.                MOV     SI,OFFSET DTA
  3112.                MOV     DX,PRINTER
  3113.                SUB     DI,SI
  3114.                MOV     CX,DI
  3115.  
  3116.                CMP     PRINTER_FLAG,1
  3117.                JZ      PRINTER_COM
  3118.                MOV     DX,SI
  3119.                JMP     OUTPUT2
  3120.  
  3121. PRINTER_COM:   CALL    PRINT_A_CHAR
  3122.                JC      DO_TOTAL_END
  3123.                LOOP    PRINTER_COM
  3124.                MOV     AL,FF
  3125.                CALL    PRINT_IT
  3126.  
  3127. DO_TOTAL_END:  RET
  3128.  
  3129. ;----------------------;
  3130. STORE_CRLF:    MOV     AL,CR
  3131.                STOSB
  3132.                MOV     AL,LF
  3133.                STOSB
  3134.                RET
  3135.  
  3136. ;--------------------------------------------------------;
  3137. ; INPUT: SI-> Journal field; OUTPUT: DX:AX = number * 100.
  3138.  
  3139. DECIMAL_FLAG   DB      ?                       ; =1 if decimal point found.
  3140. DECIMAL_CNT    DB      ?                       ; Initialized to 2.
  3141.  
  3142. ACCUMULATE:    PUSH    BP                      ;Preserve.
  3143.                MOV     DECIMAL_FLAG,0          ;Initialize flag
  3144.                MOV     DECIMAL_CNT,2           ; and counter.
  3145.                MOV     CX,NUM_SIZE             ;Length of field.
  3146.                XOR     DX,DX
  3147.                XOR     BP,BP                   ;DX:BP = number; zero to start.
  3148.  
  3149. NEXT_ACC:      LODSB
  3150.                CMP     AL,"."                  ;Decimal point?
  3151.                JNZ     CK_NUM
  3152.                MOV     DECIMAL_FLAG,1
  3153.                JMP     SHORT LOOP_ACC
  3154.  
  3155. CK_NUM:        SUB     AL,"0"                  ;Between 0 and 9?
  3156.                JB      LOOP_ACC
  3157.                CMP     AL,9
  3158.                JA      LOOP_ACC
  3159.                CMP     DECIMAL_FLAG,1          ;Decimal portion?
  3160.                JNZ     ACC
  3161.                CMP     DECIMAL_CNT,0           ;If yes, two decimals yet?
  3162.                JZ      LOOP_ACC                ;If yes, skip.
  3163.                DEC     DECIMAL_CNT             ;Else decrement.
  3164.  
  3165. ACC:           CBW
  3166.                XCHG    AX,BP
  3167.                CALL    MULTIPLY                ;Last result * 10.
  3168.                ADD     BP,AX                   ;Add in new number.
  3169.                ADC     DX,0
  3170. LOOP_ACC:      LOOP    NEXT_ACC
  3171.  
  3172.                MOV     AX,BP
  3173.                MOV     CL,DECIMAL_CNT          ;Number of decimal places
  3174.                XOR     CH,CH                   ; remaining.
  3175.                JCXZ    ACC_END
  3176. NEXT_DEC:      CALL    MULTIPLY
  3177.                LOOP    NEXT_DEC
  3178. ACC_END:       POP     BP
  3179.                RET
  3180.  
  3181. ;----------------------;
  3182. ; INPUT: DX:AX * 10
  3183.  
  3184. MULTIPLY:      PUSH    DX                      ;Save high half.
  3185.                MOV     BX,10                   ;       DX:AX
  3186.                MUL     BX                      ;     *    BX
  3187.                MOV     DI,AX                   ;     -------
  3188.                POP     AX                      ;       DX:AX
  3189.                PUSH    DX                      ; +  DX:AX
  3190.                MUL     BX                      ; ===========
  3191.                POP     DX                      ;       DX:AX
  3192.                ADD     DX,AX
  3193.                MOV     AX,DI
  3194.                RET
  3195.  
  3196. ;--------------------------------------;
  3197. ; INPUT: DX:AX = number; DI -> storage
  3198.  
  3199. AMOUNT_ASCII:  MOV     BX,100                  ;Divisor of 100.
  3200.                CMP     DX,BX                   ;Will it fit?
  3201.                JB      AMOUNT_OK               ;If yes, no overflow.
  3202.                NEG     DX                      ;Else, assume negative and
  3203.                NEG     AX                      ; negate.
  3204.                SBB     DX,0
  3205.                MOV     BYTE PTR [DI],"-"       ;Store minus sign.
  3206.                INC     DI
  3207.                CMP     DX,BX                   ;Assume right?  Does it fit?
  3208.                JB      AMOUNT_OK
  3209.                CALL    BEEP                    ;If no, beep and exit.
  3210.                JMP     SHORT AMOUNT_END
  3211.  
  3212. AMOUNT_OK:     MOV     BYTE PTR [DI],"$"
  3213.                INC     DI
  3214.                DIV     BX
  3215.                PUSH    DX
  3216.  
  3217.                MOV     BX,10                   ;Divisor of 10.
  3218.                XOR     CX,CX                   ;Count of ASCII chars.
  3219. NEXT_AMOUNT:   CMP     CX,3                    ;Insert comma delimiter?
  3220.                JNZ     NEXT_AMOUNT2
  3221.                MOV     DL,","
  3222.                PUSH    DX
  3223.                INC     CX
  3224. NEXT_AMOUNT2:  XOR     DX,DX                   ;Zero in high half.
  3225.                DIV     BX
  3226.                ADD     DL,"0"                  ;Convert to ASCII.
  3227.                PUSH    DX
  3228.                INC     CX
  3229.                OR      AX,AX                   ;Continue until no integer.
  3230.                JNZ     NEXT_AMOUNT
  3231.  
  3232. NEXT_NUMBER2:  POP     AX                      ;Display number.
  3233.                STOSB
  3234.                LOOP    NEXT_NUMBER2
  3235.  
  3236.                MOV     AL,"."                  ;Display decimal point.
  3237.                STOSB
  3238.                POP     AX
  3239.                DIV     BL
  3240.                ADD     AX,"0" SHL 8 + "0"      ;Display decimal remainder.
  3241.                STOSB
  3242.                MOV     AL,AH
  3243.                STOSB
  3244. AMOUNT_END:    RET
  3245.  
  3246. ;----------------------;
  3247. ; Selection sort algorithm.
  3248.  
  3249. SORT:          MOV     SI,OFFSET REPORT_INDEX  ;SI = first record.
  3250.  
  3251. NEXT_SORT:     MOV     AX,SI                   ;Carry source pointer in AX.
  3252.                MOV     BX,SI                   ;Carry destination pointer in DX.
  3253.                ADD     BX,SIZE REPORT_SORT
  3254.                CMP     WORD PTR [BX],-1        ;Sort is done when last record.
  3255.                JZ      SORT_END
  3256.  
  3257.                PUSH    SI                      ;Save record pointer.
  3258. NEXT_RECORD3:  MOV     SI,AX                   ;Restore inside loop pointers.
  3259.                MOV     DI,BX
  3260.                MOV     CX,SIZE DATE / 2
  3261.                REPZ    CMPSW                   ;Compare the name fields.
  3262.                JB      NO_SWITCH               ;If below, no switch.
  3263. SWAP:          MOV     AX,BX                   ;Else, AX = selected record.
  3264.  
  3265. NO_SWITCH:     ADD     BX,SIZE REPORT_SORT     ;Move to next record in list.
  3266.                CMP     WORD PTR [BX],-1        ;End of list?
  3267.                JNZ     NEXT_RECORD3            ;If no, continue.
  3268.  
  3269.                POP     SI                      ;Else, restore outside loop ptr.
  3270.                CMP     SI,BX                   ;Did we make a selection?
  3271.                JZ      SELECT_LOOP             ;If no, go to next list.
  3272.  
  3273.                PUSH    SI                      ;Else, save pointer.
  3274.                MOV     CX,SIZE REPORT_SORT / 2
  3275.                MOV     DI,AX
  3276. NEXT_SWAP:     MOV     AX,[DI]                 ;Swap the selection into place.
  3277.                MOVSW
  3278.                MOV     [SI - 2],AX
  3279.                LOOP    NEXT_SWAP
  3280.                POP     SI
  3281.  
  3282. SELECT_LOOP:   ADD     SI,SIZE REPORT_SORT     ;Next record.
  3283.                JMP     NEXT_SORT
  3284.  
  3285. SORT_END:      RET
  3286.  
  3287. ;***************************************************************************;
  3288. SETUP_CODES    DB      10 DUP (0), 0           ;Printer setup codes.
  3289. PRINTER        DW      ?
  3290.  
  3291. PRINT:         CALL    HIDE_CURSOR
  3292.                MOV     AX,1
  3293.                CALL    CALC_ADDR
  3294.                ADD     DI,9 * 2
  3295.                MOV     SI,OFFSET SCH_REPORT_MSG
  3296.                CALL    POP_WINDOW              ;Display window.
  3297.  
  3298. NEXT_PRINT1:   CALL    GETKEY                  ;Get a keystroke.
  3299.                JNC     NEXT_PRINT3
  3300.                JMP     PRINT_DONE              ;If Esc, exit.
  3301. NEXT_PRINT3:   MOV     PRINTER,0
  3302.                MOV     PRINTER_FLAG,1
  3303.                CMP     AL,F7_SCAN
  3304.                JZ      FIX_SCREEN
  3305.                MOV     PRINTER,1
  3306.                CMP     AL,F8_SCAN
  3307.                JZ      FIX_SCREEN
  3308.                MOV     PRINTER_FLAG,0
  3309.                CMP     AL,F9_SCAN
  3310.                JNZ     NEXT_PRINT1
  3311.                CALL    GET_FILENAME
  3312.                JC      PRINT_DONE
  3313.  
  3314. FIX_SCREEN:    MOV     SI,OFFSET APP_MENU
  3315.                CALL    POP_MENU                ;Fix screen cause that's where
  3316.                                                ; we're getting our data.
  3317.                MOV     AX,1
  3318.                CALL    CALC_ADDR               ;Printing starts with row 1.
  3319.                MOV     BX,DI
  3320.                MOV     BP,24
  3321.                MOV     DI,OFFSET DTA
  3322.  
  3323. NEXT_PRINT:    MOV     SI,BX
  3324.                MOV     CX,80                   ;80 characters/line.
  3325. NEXT_PRINT2:   CALL    GET_CHAR
  3326.                CALL    CK_IBM
  3327.                STOSB
  3328.                LOOP    NEXT_PRINT2
  3329.                CALL    STORE_CRLF
  3330.                ADD     BX,CRT_WIDTH
  3331.                DEC     BP
  3332.                JNZ     NEXT_PRINT
  3333.                MOV     CX,9
  3334. NEXT_CRLF:     CALL    STORE_CRLF
  3335.                LOOP    NEXT_CRLF
  3336.  
  3337.                SUB     DI,OFFSET DTA
  3338.                MOV     CX,DI
  3339.                CMP     PRINTER_FLAG,1
  3340.                JZ      PRINT_SCH
  3341.  
  3342.                MOV     BX,OUTPUT_HANDLE
  3343.                MOV     DX,OFFSET DTA
  3344.                MOV     AH,40H
  3345.                CALL    INT21_IO
  3346.                MOV     AH,3EH
  3347.                CALL    INT21_IO
  3348.                JMP     SHORT PRINT_DONE
  3349.  
  3350.  
  3351. PRINT_SCH:     CALL    PRINTER_SETUP
  3352.                JC      PRINT_DONE
  3353.                MOV     SI,OFFSET DTA
  3354. NEXT_PRINT_SCH:MOV     DX,PRINTER
  3355.                CALL    PRINT_A_CHAR
  3356.                JC      PRINT_DONE
  3357.                LOOP    NEXT_PRINT_SCH
  3358.  
  3359. PRINT_DONE:    MOV     REPAINT_FLAG,1
  3360.                RET
  3361.  
  3362. ;----------------------------------------------;
  3363. CK_IBM:        TEST    AL,10000000B
  3364.                JZ      IBM_END
  3365.                CMP     IBM_FLAG,1
  3366.                JZ      IBM_END
  3367.                PUSH    DI
  3368.                PUSH    CX
  3369.                MOV     DI,OFFSET IBM_CHARS
  3370.                MOV     CX,CHARS_LEN
  3371.                REPNZ   SCASB
  3372.                ADD     DI,CHARS_LEN - 1
  3373.                MOV     AL,[DI]
  3374.                POP     CX
  3375.                POP     DI
  3376. IBM_END:       RET
  3377.  
  3378. ;----------------------------------------------;
  3379. PRINT_A_CHAR:  LODSB
  3380. PRINT_IT:      PUSH    AX
  3381.                MOV     AH,2
  3382.                INT     17H
  3383.                TEST    AH,00101001B            ;Printer ready?
  3384.                JNZ     NOT_READY
  3385.                TEST    AH,11111001B
  3386.                JNZ     DO_PRINT
  3387. NOT_READY:     POP     AX
  3388.                CALL    BEEP                    ;If no, beep and exit.
  3389.                STC
  3390.                JMP     SHORT PRINT_END
  3391. DO_PRINT:      POP     AX
  3392.                XOR     AH,AH                   ;Print via BIOS.
  3393.                INT     17H
  3394.                CLC
  3395. PRINT_END:     RET
  3396.  
  3397. ;----------------------------------------------;
  3398. PRINT_CRLF:    MOV     AL,CR
  3399.                CALL    PRINT_IT
  3400.                JC      CRLF_END
  3401.                MOV     AL,LF
  3402.                CALL    PRINT_IT
  3403. CRLF_END:      RET
  3404.  
  3405. ;----------------------;
  3406.  
  3407. PRINTER_SETUP: MOV     SI,OFFSET SETUP_CODES   ;Send printer setup codes.
  3408. PRINTER_STRING:MOV     DX,PRINTER
  3409. P_STRING:      LODSB
  3410.                OR      AL,AL
  3411.                JZ      SETUP_END2
  3412.                CALL    PRINT_IT
  3413.                JNC     P_STRING
  3414. SETUP_END2:    RET
  3415.  
  3416. ;**********************************************;
  3417. ;       S U B R O U T I N E S                  ;
  3418. ;**********************************************;
  3419. ;INPUT: AL = Scan code; DI -> Valid scan codes table; CX = length of table
  3420. DISPATCH:      PUSH    AX
  3421.                PUSH    DX
  3422.                PUSH    BP
  3423.                MOV     BP,CX
  3424.                MOV     DX,DI
  3425.                ADD     DX,CX
  3426.                REPNZ   SCASB                   ;Scan for match.
  3427.                JZ      DO_DISPATCH
  3428.                POP     BP
  3429.                POP     DX
  3430.                JMP     SHORT NO_DISPATCH
  3431. DO_DISPATCH:   SUB     BP,CX
  3432.                DEC     BP
  3433.                SHL     BP,1
  3434.                ADD     BP,DX
  3435.                MOV     DI,BP                   ;Calc address of subroutine.
  3436.                POP     BP
  3437.                POP     DX
  3438.                CALL    [DI]                    ;Process the command.
  3439. NO_DISPATCH:   CLC
  3440. DISPATCH_END:  POP     AX
  3441.                RET
  3442.  
  3443. ;----------------------------------------------;
  3444. PERMANENT:     CMP     MODIFY_FLAG,1           ;Any changes been made?
  3445.                JNZ     PERMANENT_END           ;If no, done.
  3446.                MOV     MODIFY_FLAG,0
  3447.                CALL    HIDE_CURSOR
  3448.                MOV     AX,10
  3449.                CALL    CALC_ADDR
  3450.                ADD     DI,25 * 2
  3451.                MOV     SI,OFFSET PERMANENT_MSG
  3452.                CALL    POP_WINDOW              ;Display "Changes to disk?"
  3453.  
  3454. QUERY:         CALL    GETKEY
  3455.                JC      PERMANENT_END
  3456.                CMP     AL,N_SCAN
  3457.                JZ      PERMANENT_END
  3458.                CMP     AL,Y_SCAN               ;If "Y", then save.
  3459.                JNZ     QUERY
  3460.                JMP     SHORT SAVE2
  3461.  
  3462. PERMANENT_END: RET
  3463.  
  3464. ;----------------------------------------------;
  3465. SAVE:          CALL    SAVE2                   ;Save appointments.
  3466.                JC      F2_END
  3467.                MOV     AX,1
  3468.                CALL    CALC_ADDR
  3469.                ADD     DI,2
  3470.                MOV     SI,OFFSET SAVED_MSG
  3471.                CALL    POP_WINDOW              ;Display saved message.
  3472.                CALL    PAUSE                   ;Pause for keystroke.
  3473. F2_END:        RET
  3474.  
  3475.  
  3476. SAVE2:         MOV     MODIFY_FLAG,0
  3477.                CALL    OPEN                    ;Open data file.
  3478.                JNC     SAVE_HANDLE
  3479.                XOR     CX,CX                   ;If doesn't exist, create one.
  3480.                MOV     AH,3CH
  3481.                CALL    INT21_IO
  3482.                JBE     FAILED
  3483.                MOV     BX,AX
  3484.  
  3485. SAVE_HANDLE:   MOV     BP,AX
  3486.  
  3487. CK_EOF:        CALL    READ_DATE               ;Read date of data.
  3488.                JBE     FAILED_CLOSE
  3489.                OR      AX,AX                   ;EOF?
  3490.                JNZ     MATCH_DATE              ;If yes, append data.
  3491.                CALL    GET_SPACE
  3492.                JBE     FAILED_CLOSE
  3493.                CMP     BX,2                    ;At least two clusters free?
  3494.                MOV     BX,BP                   ;Retrieve file handle.
  3495.                JAE     ENOUGH_ROOM
  3496.                CALL    CLOSE_SAVE
  3497.                MOV     SI,OFFSET DISK_FULL_MSG
  3498.                JMP     SHORT FAILED_MSG
  3499.  
  3500. ENOUGH_ROOM:   CALL    WRITE_APP               ;Write the data.
  3501.                JMP     SHORT CLOSE_SAVE        ;Done.
  3502.  
  3503. MATCH_DATE:    CMP     CX,YEAR_CUR             ;Date of data on disk
  3504.                JNZ     NO_MATCH                ; match appointment date?
  3505.                CMP     DX,DAY_MON_CUR
  3506.                JZ      GOT_DATE                ;If yes, write over.
  3507. NO_MATCH:      CALL    NEXT_RECORD             ;Else, search next record.
  3508.                JBE     FAILED_CLOSE
  3509.                JMP     CK_EOF
  3510.  
  3511. GOT_DATE:      CALL    WRITE_APP2
  3512.                JBE     FAILED_CLOSE
  3513.  
  3514. CLOSE_SAVE:    MOV     AH,3EH                  ;Close data file.
  3515.                CALL    INT21_IO
  3516.                MOV     REPAINT_FLAG,1
  3517. SAVE_END:      RET
  3518.  
  3519. FAILED_CLOSE:  MOV     AH,3EH
  3520.                CALL    INT21_IO
  3521. FAILED:        MOV     SI,OFFSET PERMANENT_FAIL
  3522. FAILED_MSG:    MOV     AX,10
  3523.                CALL    CALC_ADDR
  3524.                ADD     DI,25 * 2
  3525.  
  3526.                CALL    POP_WINDOW              ;If failed, display failed
  3527.                CALL    FLUSH_KEY               ; message.
  3528.                XOR     AH,AH                   ;Pause.
  3529.                INT     16H
  3530.                MOV     REPAINT_FLAG,1
  3531.                STC
  3532.                RET
  3533.  
  3534. ;----------------------------------------------;
  3535. OPEN:          MOV     DX,OFFSET PATH
  3536.                MOV     AX,3D02H                ;Open data file for reading
  3537.                CALL    INT21_IO                ; and writing.
  3538.                MOV     BX,AX                   ;Filehandle.
  3539.                RET
  3540.  
  3541. ;----------------------------------------------;
  3542. ; OUTPUT: CX = Year; DH = Month; DL = Day
  3543. READ_DATE:     MOV     CX,SIZE DATE_BINARY
  3544. READ_RECORD:   MOV     DX,OFFSET DTA
  3545.                MOV     AH,3FH                  ;Read first four bytes.
  3546.                CALL    INT21_IO
  3547.                MOV     CX,WORD PTR DTA.DATE_BINARY      ;Return binary date.
  3548.                MOV     DX,WORD PTR DTA.DATE_BINARY + 2
  3549.                RET
  3550.  
  3551. ;----------------------------------------------;
  3552. GET_SPACE:     MOV     DL,BYTE PTR PATH
  3553.                SUB     DL,"A" - 1
  3554.                MOV     AH,36H                  ;See if room to tack on app.
  3555.                CALL    INT21_IO
  3556.                RET
  3557.  
  3558. ;----------------------------------------------;
  3559. NEXT_RECORD:   XOR     CX,CX
  3560.                MOV     DX,SIZE DATE_ASCII+SIZE JOU_FIELDS
  3561.                CMP     STATE,OFFSET JOURNAL
  3562.                JZ      NEXT_RECORD2
  3563.                MOV     DX,SIZE DATE_ASCII+SIZE DATA_TEXT+SIZE NOTEPAD_TEXT
  3564. NEXT_RECORD2:  MOV     AX,4201H
  3565.                CALL    INT21_IO                ;Bump pointer to next record.
  3566.                RET
  3567.  
  3568. ;----------------------------------------------;
  3569. ; OUTPUT: CY = 1 OR ZF = 1 if write failed.
  3570. WRITE_APP:     MOV     DX,OFFSET YEAR_CUR      ;Write binary date.
  3571.                MOV     CX,SIZE DATE_BINARY
  3572.                CALL    WRITE_RECORD
  3573.                JBE     WRITE_APP_END
  3574.  
  3575. WRITE_APP2:    MOV     DX,OFFSET APP_DATE      ;Write ASCII date.
  3576.                MOV     CX,DATE_LEN
  3577.                CALL    WRITE_RECORD
  3578.                JBE     WRITE_APP_END
  3579.  
  3580.                CMP     STATE,OFFSET APPOINTMENT
  3581.                JZ      WRITE_APP3
  3582.  
  3583.                PUSH    BX                      ;Handle
  3584.                MOV     DI,OFFSET DTA.DATA_TEXT
  3585.                MOV     BP,FIELDS_CNT
  3586.                MOV     BX,OFFSET ACC_FIELDS
  3587.                MOV     DL,APP_WIDTH
  3588.  
  3589. NEXT_JOU_STORE:MOV     AL,[BX]
  3590.                INC     BX
  3591.                MUL     DL
  3592.                MOV     SI,AX
  3593.                MOV     AL,[BX]
  3594.                INC     BX
  3595.                XOR     AH,AH
  3596.                ADD     SI,AX
  3597.                ADD     SI,OFFSET JOU_START
  3598.  
  3599.                MOV     CX,[BX]
  3600.                INC     BX
  3601.                INC     BX
  3602.                REP     MOVSB
  3603.  
  3604.                DEC     BP
  3605.                JNZ     NEXT_JOU_STORE
  3606.                POP     BX
  3607.  
  3608.                MOV     DX,OFFSET DTA.DATA_TEXT
  3609.                MOV     CX,SIZE JOU_FIELDS   
  3610.                CALL    WRITE_RECORD
  3611.                JMP     SHORT WRITE_APP_END
  3612.  
  3613.  
  3614.  
  3615. WRITE_APP3:    MOV     SI,APP_HEIGHT           ;16 Rows.
  3616.                MOV     DI,OFFSET APP_LEFT_START
  3617.                MOV     CX,APP_LEN
  3618. NEXT_WRITE:    MOV     DX,DI
  3619.                CALL    WRITE_RECORD            ;Write appointments.
  3620.                JBE     WRITE_APP_END
  3621.                ADD     DX,APP_LEN + APP_COL_SPACE
  3622.                CALL    WRITE_RECORD
  3623.                JBE     WRITE_APP_END
  3624.                ADD     DI,APP_WIDTH
  3625.                DEC     SI
  3626.                JNZ     NEXT_WRITE
  3627.  
  3628. WRITE_NOTEPAD: MOV     DX,OFFSET NOTEPAD
  3629.                MOV     CX,NOTEPAD_LEN
  3630.                CALL    WRITE_RECORD            ;Write Notepad.
  3631.                JBE     WRITE_APP_END
  3632.                INC     SI                      ;Flag as successful.
  3633.                CLC
  3634. WRITE_APP_END: RET
  3635.  
  3636. WRITE_RECORD:  MOV     AH,40H                  ;DOS write.
  3637.                CALL    INT21_IO
  3638.                RET
  3639.  
  3640. ;----------------------------------------------;
  3641. READ_APP:      MOV     DX,OFFSET DTA.DATE_ASCII
  3642.                MOV     CX,SIZE DATE_ASCII+SIZE DATA_TEXT+SIZE NOTEPAD_TEXT
  3643.                MOV     AH,3FH
  3644.                CALL    INT21_IO                ;Read data record.
  3645.                RET
  3646.  
  3647. ;----------------------------------------------;
  3648. BEEP:          PUSH    AX
  3649.                PUSH    BX
  3650.                PUSH    CX
  3651.                PUSH    DX
  3652.                CALL    SETUP_BELL
  3653.  
  3654.                MOV     CX,1                    ;One timer tick.
  3655.                CALL    DELAY                   ;Wait till clock rolls over.
  3656.                CALL    TOGGLE_BELL
  3657.  
  3658.                MOV     CX,1                    ;Number of seconds.
  3659.                CALL    DELAY                   ;Delay seconds.
  3660.                CALL    RESET_BELL
  3661.                POP     DX
  3662.                POP     CX
  3663.                POP     BX
  3664.                POP     AX
  3665.                RET
  3666.  
  3667. SETUP_BELL:    MOV     BX,CS:NOTE
  3668.                XOR     AX,AX
  3669.                MOV     DX,12H                  ;120000h dividend constant.
  3670.                DIV     BX                      ; Divide to get
  3671.                MOV     BX,AX                   ; 8253 countdown.
  3672.                CALL    RESET_BELL
  3673.                MOV     AL,0B6H                 ;Channel 2 speaker functions.
  3674.                OUT     43H,AL                  ;8253 Mode Control.
  3675.                JMP     $+2                     ;IO delay.
  3676.                MOV     AX,BX                   ;Retrieve countdown.
  3677.                OUT     42H,AL                  ;Channel 2 LSB.
  3678.                JMP     $+2
  3679.                MOV     AL,AH                   ;Channel 2 MSB.
  3680.                OUT     42H,AL
  3681.                RET
  3682.  
  3683. RESET_BELL:    IN      AL,PORT_B               ;Port B.
  3684.                AND     AL,NOT 3                ;Turn off speaker.
  3685.                JMP     $+2
  3686.                OUT     PORT_B,AL
  3687.                RET
  3688.  
  3689. FLIP_BELL:     DEC     BELL_CNT
  3690.                JNZ     TOGGLE_BELL
  3691.                CALL    RESET_BELL
  3692.                CMP     PROGRAM_STATUS,0        ;Are we popped up.
  3693.                JNZ     FLIP_END                ;If yes, done.
  3694.                CMP     NOPOPUP_FLAG,1          ;User requested no-popup?
  3695.                JZ      FLIP_END                ;If yes, done.
  3696.                MOV     POPUP_FLAG,1            ;Else, try to popup.
  3697. FLIP_END:      MOV     BELL_FLAG,0             ;Reset bell flag.
  3698.                RET
  3699.  
  3700. TOGGLE_BELL:   IN      AL,PORT_B
  3701.                XOR     AL,3
  3702.                JMP     $+2
  3703.                OUT     PORT_B,AL
  3704.                RET
  3705.  
  3706. ;----------------------------------------------;
  3707. ; INPUT: CX = 1/18 seconds.                    ;
  3708. DELAY:         PUSH    DS                      ;Preserve data segment.
  3709.                MOV     AX,40H                  ;Point to BIOS data segment.
  3710.                MOV     DS,AX
  3711. NEXT_TICK:     MOV     AX,DS:[6CH]             ;Retrieve timer low.
  3712. NEXT_DELAY:    MOV     DX,DS:[6CH]             ;Retrieve timer low.
  3713.                CMP     DX,AX                   ;Have we timed out?
  3714.                JZ      NEXT_DELAY              ;If not, wait until timer tick.
  3715.                LOOP    NEXT_TICK
  3716.                POP     DS                      ;Restore data segment.
  3717.                RET
  3718.  
  3719. ;----------------------------------------------;
  3720. SAVE_SCREEN:   XOR     AX,AX                   ;Top left of screen.
  3721.                CALL    CALC_ADDR
  3722.                MOV     SI,AX
  3723.                MOV     DI,OFFSET WIN_SAVE      ;Storage space.
  3724.                MOV     CX,25
  3725.                MOV     BP,80
  3726.                CALL    DO_SAVE                 ;Save entire screen.
  3727.                RET
  3728.  
  3729. DO_SAVE:       PUSH    DS
  3730.                MOV     DX,STATUS_REG
  3731.                MOV     DS,VIDEO_SEG
  3732.  
  3733. NEXT_SAVE:     PUSH    CX
  3734.                PUSH    SI
  3735.                MOV     CX,BP
  3736. NEXT_SAVE2:    IN      AL,DX                   ;Get status.
  3737.                RCR     AL,1                    ;Is it low?
  3738.                JC      NEXT_SAVE2              ;If not, wait until it is.
  3739.                CLI                             ;No more interrupts.
  3740.  
  3741. HWAIT3:        IN      AL,DX                   ;Get status.
  3742.                RCR     AL,1                    ;Is it high?
  3743.                JNC     HWAIT3                  ;If no, wait until it is.
  3744.                MOVSW
  3745.                STI
  3746.                LOOP    NEXT_SAVE2
  3747.                POP     SI
  3748.                ADD     SI,CS:CRT_WIDTH         ;Next row.
  3749.                POP     CX
  3750.                LOOP    NEXT_SAVE
  3751.                POP     DS
  3752.                RET
  3753.  
  3754. ;----------------------------------------------;
  3755. RESTORE_SCREEN:XOR     AX,AX                   ;Top left of screen.
  3756.                CALL    CALC_ADDR
  3757.                MOV     SI,OFFSET WIN_SAVE
  3758.                MOV     CX,25
  3759.                MOV     BP,80
  3760.                CALL    DO_RESTORE              ;Restore all 25 rows.
  3761.                RET
  3762.  
  3763. DO_RESTORE:    PUSH    ES
  3764.                MOV     ES,VIDEO_SEG
  3765.                MOV     DX,STATUS_REG
  3766.  
  3767. NEXT_SCREEN:   PUSH    CX
  3768.                PUSH    DI
  3769.                MOV     CX,BP
  3770. NEXT_SCREEN2:  IN      AL,DX                   ;Get status.
  3771.                RCR     AL,1                    ;Is it low?
  3772.                JC      NEXT_SCREEN2            ;If not, wait until it is.
  3773.                CLI                             ;No more interrupts.
  3774.  
  3775. HWAIT2:        IN      AL,DX                   ;Get status.
  3776.                RCR     AL,1                    ;Is it high?
  3777.                JNC     HWAIT2                  ;If no, wait until it is.
  3778.                MOVSW
  3779.                STI
  3780.                LOOP    NEXT_SCREEN2
  3781.  
  3782.                POP     DI
  3783.                ADD     DI,CRT_WIDTH            ;Next row.
  3784.                POP     CX
  3785.                LOOP    NEXT_SCREEN
  3786.                POP     ES
  3787.                RET
  3788.  
  3789. ;----------------------------------------------;
  3790. POP_MENU:      XOR     AX,AX                   ;Top left of screen.
  3791.                CALL    CALC_ADDR
  3792.  
  3793. ;--------------------------------------------------------;
  3794. ; INPUT: DI -> Video destination; SI -> Window to popup. ;
  3795. POP_WINDOW:    PUSH    ES
  3796.                MOV     DX,STATUS_REG
  3797.                MOV     ES,VIDEO_SEG
  3798.  
  3799. NEXT_POP:      PUSH    DI
  3800. NEXT_WIN:      LODSB
  3801.                CMP     AL,7                    ;Format code?
  3802.                JBE     CK_COMPRESS
  3803.                CALL    WRITE_SCREEN            ;If no, write to screen.
  3804.                JMP     NEXT_WIN
  3805.  
  3806. CK_COMPRESS:   DEC     AL                      ;Character to repeat?
  3807.                JNS     CK_DROP
  3808.                LODSW                           ;If yes, get count and char.
  3809.                MOV     CL,AL
  3810.                XOR     CH,CH
  3811.                XCHG    AL,AH
  3812.                CALL    REPEAT_CHAR             ;Repeat to screen.
  3813.                JMP     NEXT_WIN
  3814.  
  3815. CK_DROP:       DEC     AL                      ;Transparent black attribute?
  3816.                JNS     CK_COLOR
  3817.                MOV     CX,2
  3818.                CALL    DROP_SHADE              ;If yes, display drop shade.
  3819.                JMP     SHORT STRING_END
  3820.  
  3821. CK_COLOR:      DEC     AL                      ;New color?
  3822.                JNS     CK_STRING
  3823.                LODSB
  3824.                MOV     BL,AL
  3825.                XOR     BH,BH
  3826.                MOV     BH,BYTE PTR COLOR[BX]   ;If yes, look it up.
  3827.                JMP     NEXT_WIN
  3828.  
  3829. CK_STRING:     DEC     AL                      ;End of string?
  3830.                JNS     DROP_STRING
  3831. STRING_END:    POP     DI
  3832.                ADD     DI,CRT_WIDTH            ;If yes, go to next line.
  3833.                CMP     BYTE PTR [SI],-1        ;End of window?
  3834.                JNZ     NEXT_POP                ;If yes, done.
  3835.                JMP     SHORT POP_END
  3836.  
  3837. DROP_STRING:   DEC     AL                      ;Bottom drop shade?
  3838.                JNS     INSERT_DATE
  3839.                LODSB                           ;Get length of window.
  3840.                CBW
  3841.                MOV     CX,AX
  3842.                ADD     DI,4                    ;Shift right 2 columns.
  3843.                CALL    DROP_SHADE
  3844.                POP     DI
  3845.                JMP     SHORT POP_END
  3846.  
  3847. INSERT_DATE:   DEC     AL                      ;Special date insert?
  3848.                JNS     INSERT_APP
  3849.                CALL    DATE_INSERT
  3850.                JMP     NEXT_WIN
  3851.  
  3852. INSERT_APP:    DEC     AL                      ;Special small char. insert?
  3853.                JNS     SKIP
  3854.                CALL    APP_INSERT
  3855.                JMP     NEXT_WIN
  3856.  
  3857. SKIP:          LODSB                           ;Else, skip some characters.
  3858.                XOR     AH,AH
  3859.                ADD     DI,AX
  3860.                JMP     NEXT_WIN
  3861.  
  3862. POP_END:       POP     ES
  3863.                RET
  3864.  
  3865. ;----------------------------------------------;
  3866. DROP_SHADE:    MOV     BL,8
  3867.                INC     DI
  3868. ATTR:          IN      AL,DX                   ;Get status.
  3869.                RCR     AL,1                    ;Is it low?
  3870.                JC      ATTR                    ;If not, wait until it is.
  3871.                CLI                             ;No more interrupts.
  3872.  
  3873. HWAIT6:        IN      AL,DX                   ;Get status.
  3874.                RCR     AL,1                    ;Is it high?
  3875.                JNC     HWAIT6                  ;If no, wait until it is.
  3876.                MOV     AL,BL
  3877.                STOSB
  3878.                STI                             ;Interrupts back on.
  3879.                INC     DI
  3880.                LOOP    ATTR
  3881.                RET
  3882.  
  3883. ;----------------------------------------------;
  3884. DATE_INSERT:   PUSH    BX
  3885.                MOV     AH,WEEKDAY
  3886.                INC     DAY_COUNTER
  3887.                MOV     AL,DAY_COUNTER
  3888.                CMP     AL,AH                   ;Are we to first day of month?
  3889.                JBE     DO_BLANK                ;If no, blanks.
  3890.                SUB     AL,AH
  3891.                CBW
  3892.                CMP     AL,LAST_DAY             ;Are we past last day of month?
  3893.                JA      DO_BLANK                ;If yes, blanks.
  3894.                CMP     AL,DAY_TODAY
  3895.                JNZ     DO_DAY
  3896.                MOV     CL,MONTH_TODAY
  3897.                CMP     CL,MONTH_CAL
  3898.                JNZ     DO_DAY
  3899.                MOV     CX,YEAR_TODAY
  3900.                CMP     CX,YEAR_CAL
  3901.                JNZ     DO_DAY
  3902.                MOV     BH,COLOR.Y              ;Use highlight color if today.
  3903. DO_DAY:        CALL    DECIMAL_ASCII           ;Write the date.
  3904.                JMP     SHORT D_INSERT_END
  3905.  
  3906. DO_BLANK:      MOV     AL,SPACE
  3907.                CALL    WRITE_SCREEN
  3908.                MOV     AL,SPACE
  3909.                CALL    WRITE_SCREEN
  3910.  
  3911. D_INSERT_END:  POP     BX
  3912.                RET
  3913.  
  3914. ;----------------------------------------------;
  3915. APP_INSERT:    PUSH    BX
  3916.                MOV     BH,COLOR.A              ;Assume small block color.
  3917.                MOV     AH,WEEKDAY
  3918.                MOV     BP,BLOCK_ROW            ;Block row index (0 or 1).
  3919.                INC     BLOCK_COUNTER[BP]       ;Block day counter.
  3920.                MOV     AL,BLOCK_COUNTER[BP]
  3921.                CMP     AL,AH                   ;If before first day, blanks.
  3922.                JBE     DO_BLANK2
  3923.  
  3924.                PUSH    AX                      ;Save block counter.
  3925.                CBW
  3926.                MOV     CL,7
  3927.                DIV     CL
  3928.                OR      AH,AH
  3929.                JNZ     CALC_BLOCK
  3930.                XOR     BLOCK_ROW,1             ;Once a week flip block row index
  3931.  
  3932. CALC_BLOCK:    POP     AX
  3933.                SUB     AL,AH
  3934.                CMP     AL,LAST_DAY             ;Past last day?
  3935.                JA      DO_BLANK2               ;If so, blanks.
  3936.                CBW
  3937.                CMP     AL,DAY_CAL
  3938.                JNZ     CK_ROW
  3939.                MOV     BH,COLOR.C              ;If today, user cursor color.
  3940.  
  3941. CK_ROW:        MOV     CL,3
  3942.                DEC     AX
  3943.                SHL     AX,CL                   ;Index * 8 into array.
  3944.                TEST    BP,1
  3945.                JZ      GOT_INDEX
  3946.                ADD     AX,BLOCK_COUNT / 2      ; + Array size / 2 for odd rows.
  3947.  
  3948. GOT_INDEX:     MOV     BP,AX
  3949.                MOV     CX,8
  3950. NEXT_BLOCK:    MOV     AL,APPOINTMENT_BLOCKS[BP]
  3951.                CALL    WRITE_SCREEN            ;Write the 8 block chars.
  3952.                INC     BP
  3953.                LOOP    NEXT_BLOCK
  3954.                JMP     SHORT A_INSERT_END
  3955.  
  3956. DO_BLANK2:     MOV     AL,SPACE
  3957.                MOV     CX,8
  3958.                CALL    REPEAT_CHAR
  3959.  
  3960. A_INSERT_END:  POP     BX
  3961.                RET
  3962.  
  3963. ;----------------------------------------------;
  3964. CALC_ADDR:     MUL     CRT_WIDTH               ;Address = row * screen width
  3965.                ADD     AX,CRT_START            ; + start of screen buffer.
  3966.                MOV     DI,AX
  3967.                RET
  3968.  
  3969. ;----------------------------------------------;
  3970. ;INPUT: CX=char count; AX=character
  3971. REPEAT_CHAR:   PUSH    AX
  3972.                CALL    WRITE_SCREEN
  3973.                POP     AX
  3974.                LOOP    REPEAT_CHAR
  3975.                RET
  3976.  
  3977. ;----------------------------------------------;
  3978. WRITE_SCREEN:  MOV     BL,AL                   ;Store character in BL.
  3979. HORZ_RET:      IN      AL,DX                   ;Get status.
  3980.                RCR     AL,1                    ;Is it low?
  3981.                JC      HORZ_RET                ;If not, wait until it is.
  3982.                CLI                             ;No more interrupts.
  3983.  
  3984. HWAIT:         IN      AL,DX                   ;Get status.
  3985.                RCR     AL,1                    ;Is it high?
  3986.                JNC     HWAIT                   ;If no, wait until it is.
  3987.  
  3988.                MOV     AX,BX                   ;Retrieve character; now it's OK
  3989.                STOSW                           ; to write to screen buffer.
  3990.                STI                             ;Interrupts back on.
  3991.                RET                             ;Return
  3992.  
  3993. ;----------------------------------------------;
  3994. GET_CHAR:      PUSH    DS
  3995.                PUSH    DX
  3996.                MOV     DX,STATUS_REG
  3997.                MOV     DS,VIDEO_SEG
  3998.  
  3999. HORZ_RET2:     IN      AL,DX                  ;Get status.
  4000.                RCR     AL,1                   ;Is it low?
  4001.                JC      HORZ_RET2              ;If not, wait until it is.
  4002.                CLI                            ;No more interrupts.
  4003.  
  4004. HWAIT4:        IN      AL,DX                  ;Get status.
  4005.                RCR     AL,1                   ;Is it high?
  4006.                JNC     HWAIT4                 ;If no, wait until it is.
  4007.                LODSW
  4008.                STI
  4009.                POP     DX
  4010.                POP     DS
  4011.                RET
  4012.  
  4013. ;----------------------------------------------;
  4014. DECIMAL_ASCII: MOV     CL,10
  4015.                DIV     CL
  4016.                ADD     AX,"0" SHL 8 + "0"
  4017.                PUSH    AX
  4018.                CMP     AL,"0"
  4019.                JNZ     DO_DECIMAL
  4020.                MOV     AL,SPACE
  4021. DO_DECIMAL:    CALL    WRITE_SCREEN
  4022.                POP     AX
  4023.                MOV     AL,AH
  4024.                CALL    WRITE_SCREEN
  4025.                RET
  4026.  
  4027. ;------------------------------------------------------------------------------
  4028. ; OUTPUT: AL=scan code; AH=char; CY=1 if hotkey or Esc; EXIT_FLAG=1 if hotkey
  4029. GETKEY:        MOV     AH,1                    ;Keystroke waiting?
  4030.                INT     16H
  4031.                JNZ     GETKEY1
  4032.                INT     28H                     ;DOS idle interrupt.
  4033.                JMP     GETKEY
  4034. GETKEY1:       XOR     AH,AH                   ;Get keystroke.
  4035.                INT     16H
  4036.                XCHG    AL,AH
  4037.                CMP     AL,ESC_SCAN             ;Esc key?
  4038.                JZ      EXIT_KEY
  4039.  
  4040. CK_HOT:        CMP     AL,HOT_KEY_SCAN         ;Hotkey?
  4041.                JNZ     GETKEY_END
  4042.                PUSH    AX
  4043.                MOV     AH,2
  4044.                INT     16H
  4045.                TEST    AL,HOT_SHIFT_KEY
  4046.                POP     AX
  4047.                JZ      GETKEY_END
  4048.                MOV     EXIT_FLAG,1
  4049.  
  4050. EXIT_KEY:      STC
  4051.                RET
  4052.  
  4053. GETKEY_END:    CLC
  4054.                RET
  4055.  
  4056. ;----------------------------------------------;
  4057. FLUSH_IT:      XOR     AH,AH                   ;Flush keyboard buffer.
  4058.                INT     16H
  4059. FLUSH_KEY:     MOV     AH,1
  4060.                INT     16H
  4061.                JNZ     FLUSH_IT
  4062.                RET
  4063.  
  4064. ;----------------------------------------------;
  4065. PAUSE:         MOV     AH,1                    ;Wait till keystroke in buffer.
  4066.                INT     16H
  4067.                JZ      PAUSE
  4068.                RET
  4069.  
  4070. ;---------------------------------------------;
  4071. ; Move BIOS video data into our data segment. ;
  4072. ;---------------------------------------------;
  4073. GET_BIOS_DATA: PUSH    DS
  4074.                PUSH    ES
  4075.  
  4076.                MOV     AX,40H                  ;BIOS data area.
  4077.                MOV     DS,AX
  4078.                PUSH    CS
  4079.                POP     ES
  4080.  
  4081.                MOV     SI,BIOS_ACTIVE_PAGE     ;Start with active page.
  4082.                MOV     DI,OFFSET ACTIVE_PAGE
  4083.                MOVSB                           ;Retrieve active page
  4084.                MOVSW                           ; and address of 6845 port.
  4085.                MOV     SI,BIOS_CRT_MODE        ;Retrieve CRT mode, CRT columns,
  4086.                MOV     CX,CRT_DATA_LENGTH      ; CRT length, CRT start.
  4087.                REP     MOVSB
  4088.  
  4089.                XOR     BH,BH
  4090.                MOV     DL,24                   ;Assume 24 logical rows.
  4091.                MOV     AX,1130H                ;Get Information via BIOS.
  4092.                INT     10H
  4093. STORE_ROWS:    POP     ES
  4094.                POP     DS
  4095.                MOV     CRT_ROWS,DL             ;Store rows.
  4096.  
  4097.                MOV     BH,ACTIVE_PAGE
  4098.                MOV     AH,3
  4099.                INT     10H                     ;Get Cursor mode.
  4100.                MOV     CURSOR_MODE,CX
  4101.                MOV     CURSOR_POS,DX
  4102.                MOV     DX,ADDR_6845
  4103.                ADD     DX,6
  4104.                MOV     STATUS_REG,DX
  4105.                MOV     AX,0B000H
  4106.                MOV     SCH_CURSOR,0B0CH
  4107.                CMP     DX,3BAH
  4108.                JZ      STORE_VIDEO
  4109.                MOV     SCH_CURSOR,0607H
  4110.                ADD     AX,800H
  4111. STORE_VIDEO:   MOV     VIDEO_SEG,AX            ;Video address.
  4112.                MOV     AX,CRT_COLS
  4113.                SHL     AX,1
  4114.                MOV     CRT_WIDTH,AX            ;CRT width = columns * 2.
  4115.                RET
  4116.  
  4117. ;------------------------------------------------------------------------------;
  4118. ; Read port directly for programs like 123 that do not use BIOS to set address.;
  4119. ;------------------------------------------------------------------------------;
  4120. GET_CUR_ADDR:  MOV     DX,ADDR_6845
  4121.                MOV     AL,14
  4122.                OUT     DX,AL
  4123.                INC     DX
  4124.                IN      AL,DX
  4125.                MOV     AH,AL
  4126.                DEC     DX
  4127.                MOV     AL,15
  4128.                OUT     DX,AL
  4129.                INC     DX
  4130.                IN      AL,DX
  4131.                MOV     CURSOR_ADDR,AX
  4132.                RET
  4133.  
  4134. ;----------------------------------------------;
  4135. HIDE_CURSOR:   MOV     DH,CRT_ROWS
  4136.                INC     DH
  4137.                XOR     DL,DL
  4138.  
  4139. SET_CURSOR:    PUSH    AX
  4140.                MOV     BH,ACTIVE_PAGE
  4141.                MOV     AH,2
  4142.                INT     10H
  4143.                POP     AX
  4144.                RET
  4145.  
  4146. ;------------------------------------------------------------------------------
  4147. ;IOSET vectors interrupts 1Bh, 23h and 24h to internal handlers.  IORESET
  4148. ;restores the original vector values.
  4149. ;------------------------------------------------------------------------------
  4150. IOSET          PROC    NEAR
  4151.                PUSH    ES
  4152.                MOV     AX,351BH                ;BIOS Ctrl break interrupt.
  4153.                INT     21H
  4154.                MOV     OLD1B[0],BX
  4155.                MOV     OLD1B[2],ES
  4156.                MOV     DX,OFFSET IOEXIT        ;Ignore.
  4157.                MOV     AX,251BH
  4158.                INT     21H
  4159.  
  4160.                MOV     AX,3523H                ;DOS Ctrl break interrupt.
  4161.                INT     21H
  4162.                MOV     OLD23[0],BX
  4163.                MOV     OLD23[2],ES
  4164.                MOV     DX,OFFSET IOEXIT        ;Ignore.
  4165.                MOV     AX,2523H
  4166.                INT     21H
  4167.  
  4168.                MOV     AX,3524H                ;Critical error interrupt.
  4169.                INT     21H
  4170.                MOV     OLD24[0],BX
  4171.                MOV     OLD24[2],ES
  4172.                MOV     DX,OFFSET IOERR         ;Install ours.
  4173.                MOV     AX,2524H
  4174.                INT     21H
  4175.                POP     ES
  4176.                RET
  4177. IOSET          ENDP
  4178.  
  4179. ;-------------------------------------------;
  4180. IORESET        PROC    NEAR
  4181.                PUSH    DS
  4182.                MOV     DX,OLD24[0]
  4183.                MOV     DS,OLD24[2]
  4184.                MOV     AX,2524H                ;Restore Critical.
  4185.                INT     21H
  4186.  
  4187.                MOV     DX,CS:OLD23[0]
  4188.                MOV     DS,CS:OLD23[2]
  4189.                MOV     AX,2523H                ;Restore DOS Ctrl break.
  4190.                INT     21H
  4191.  
  4192.                MOV     DX,CS:OLD1B[0]
  4193.                MOV     DS,CS:OLD1B[2]
  4194.                MOV     AX,251BH                ;Restore BIOS Ctrl break.
  4195.                INT     21H
  4196.                POP     DS
  4197.                RET
  4198. IORESET        ENDP
  4199.  
  4200. ;------------------------------------------------------------------------------
  4201. ;INITIALIZE prepares the program for residency.
  4202. ;------------------------------------------------------------------------------
  4203. SCH_DAT        DB      "SCHEDULE.DAT",0
  4204. SCH_ARC        DB      "SCHEDULE.ASC",0
  4205. JOU_DAT        DB      "JOURNAL.DAT",0
  4206. JOU_ARC        DB      "JOURNAL.ASC",0
  4207.  
  4208. PATH_END       DW      ?
  4209. PATH_LEN       EQU     100
  4210. PATH           DB      PATH_LEN DUP (0)
  4211.  
  4212. EVEN
  4213.                DB      (256 / 8) DUP ("STACK   ")
  4214. OUR_STACK      =       $
  4215. ERR_SAVE       DB      (((ERR_WIDTH + 2) * 2) * (ERR_HEIGHT + 1)) DUP (?)
  4216. WIN_SAVE       DB      ((80 * 2) * 25) DUP (?)
  4217. RESIDENT_END   =       $
  4218.                DB      16 DUP (?)              ;Allocation block.
  4219.  
  4220. SYNTAX DB  "Syntax: Journal [/I] [/U] [/Hn] [/Pn...n] [/G] [/A] [/C] [/M] [/B]",CR,LF
  4221.        DB  "/I = Install Memory-resident",CR,LF
  4222.        DB  "/U = Uninstall",CR,LF
  4223.        DB  "/H = Hotkey assignment; Ctrl or Alt plus new hotkey",CR,LF
  4224.        DB  "     eg. /H Ctrl Y or /H Alt 1;  default is Alt J",CR,LF
  4225.        DB  "/P = Printer setup string in decimal; 10 maximum.",CR,LF
  4226.        DB  "     eg. /P 27 40 115 66 is boldface on a LaserJet",CR,LF
  4227.        DB  "/G = Graphical characters in printing; Use appropriate /P",CR,LF
  4228.        DB  "     setup for your printer to switch to IBM character set",CR,LF
  4229.        DB  "/A [OFF|ON] = Appointment pop up OFF or ON; default = OFF",CR,LF
  4230.        DB  "/C [OFF|ON] = Chime OFF or ON; default = OFF",CR,LF
  4231.        DB  "/M [OFF|ON] = Midnight update pop up OFF or ON; default = OFF",CR,LF
  4232.        DB  "/B = Black and white attributes"
  4233.        DB  CR,LF,LF,"$"
  4234.  
  4235. CANT_FIND      DB      "Can't find Journal.com",CR,LF
  4236.                DB      "Change to Journal's directory before running.",CR,LF,"$"
  4237. NOT_INSTALLED  DB      "Journal not installed",CR,LF,"$"
  4238. ALREADY_MSG    DB      "Journal already installed",CR,LF,"$"
  4239. UNLOAD_MSG     DB      "Journal can't be uninstalled",CR,LF
  4240.                DB      "Uninstall resident programs in reverse order",CR,LF,"$"
  4241. NOT_ENOUGH     DB      "Not enough memory to install Journal",CR,LF,"$"
  4242. ALLOCATE_MSG   DB      "Memory allocation error",CR,LF,BELL,"$"
  4243. INSTALL_MSG    DB      "Installed",CR,LF,"$"
  4244. UNINSTALL_MSG  DB      "Uninstalled",CR,LF,"$"
  4245.  
  4246. TSR            DB      "JOURNAL.COM",0
  4247.  
  4248. CRITICAL_MSG   DB      "DOS Critical Error Flag not found",CR,LF
  4249.                DB      "Can't install",CR,LF,"$"
  4250.  
  4251. HOTKEY_MSG     DB      "Press $"
  4252. HOTKEY_MSG2    DB      " to pop-up Journal",CR,LF,"$"
  4253.  
  4254. SIDEKICK_MSG   DB      "SideKick must be loaded last.",CR,LF
  4255.                DB      "Uninstall SideKick and then install Journal",CR,LF,"$"
  4256.  
  4257. WRONG_VERSION  DB      "Needs DOS 2.0 or later$"
  4258.  
  4259. SCAN_CODES LABEL BYTE
  4260.  
  4261. DB "1",2,"2",3,"3",4,"4",5,"5",6,"6",7,"7",8,"8",9,"9",0AH,"0",0BH,"-",0CH
  4262. DB "=",0DH,"Q",10H,"W",11H,"E",12H,"R",13H,"T",14H,"Y",15H,"U",16H,"I",17H
  4263. DB "O",18H,"P",19H,"[",1AH,"]",1BH,"A",1EH,"S",1FH,"D",20H,"F",21H,"G",22H
  4264. DB "H",23H,"J",24H,"K",25H,"L",26H,";",27H,39,28H,96,29H,"\",2BH,"Z",2CH
  4265. DB "X",2DH,"C",2EH,"V",2FH,"B",30H,"N",31H,"M",32H,",",33H,".",34H,"/",35H
  4266.  
  4267. SCAN_COUNT     EQU     ($ - SCAN_CODES) / 2
  4268.  
  4269. INSTALL_FLAG   DB      0                       ; =1 if /I found.
  4270. UNINSTALL_FLAG DB      0                       ; =1 if /U found.
  4271. ALT            DB      " Alt $"
  4272. CTRL           DB      "Ctrl $"
  4273. ALT_CAPS       DB      "ALT"
  4274. CTRL_CAPS      DB      "CTRL"
  4275.  
  4276. ;----------------------------------------------;
  4277. INITIALIZE     PROC    NEAR
  4278.                CLD
  4279.                MOV     BX,OFFSET SIGNATURE     ;Point to start of code.
  4280.                NOT     BYTE PTR [BX]           ;Change a byte so no false match.
  4281.                MOV     AX,CS                   ;Store our segment in AX.
  4282.                MOV     DX,0A000H - 1
  4283. NEXT_PARAG:    INC     DX                      ;Next paragraph.
  4284.                MOV     ES,DX
  4285.                CMP     DX,AX                   ;Is it our segment?
  4286.                JZ      SAVE_SEG                ;If yes, search is done.
  4287.                MOV     SI,BX                   ;Else, point to our signature.
  4288.                MOV     DI,BX                   ; and offset of possible match.
  4289.                MOV     CX,16                   ;Check 16 bytes for match.
  4290.                REP     CMPSB
  4291.                JNZ     NEXT_PARAG              ;If no match, keep looking.
  4292.  
  4293. ;----------------------------------------------;
  4294. SAVE_SEG:      MOV     TSR_SEGMENT,ES
  4295.  
  4296.                MOV     SI,81H                  ;Point to command line.
  4297. NEXT_CAP:      LODSB                           ;Capitalize parameters.
  4298.                CMP     AL,CR
  4299.                JZ      PARSE
  4300.                CMP     AL,"a"
  4301.                JB      NEXT_CAP
  4302.                CMP     AL,"z"
  4303.                JA      NEXT_CAP
  4304.                AND     BYTE PTR [SI - 1],5FH
  4305.                JMP     SHORT NEXT_CAP
  4306.  
  4307. ;----------------------------------------------;
  4308. PARSE:         MOV     SI,81H                  ;Point to command line again.
  4309. NEXT_SWITCH:   LODSB
  4310.                CMP     AL,CR                   ;Is it carriage return?
  4311.                JNZ     CK_SPACE
  4312.                JMP     INSTALL                 ;If yes, done here.
  4313. CK_SPACE:      CMP     AL,SPACE                ;If space or below, ignore.
  4314.                JBE     NEXT_SWITCH
  4315.                CMP     AL,"/"                  ;Is it a switch character?
  4316.                JZ      GET_SWITCH              ;If yes, continue.
  4317.                CALL    ANNOUNCE
  4318.                JMP     ERROR_EXIT              ;Else, error; exit.
  4319.  
  4320. GET_SWITCH:    LODSB
  4321.                CMP     AL,CR
  4322.                JZ      INSTALL
  4323.                CMP     AL,"U"                  ;Is it "U" ?
  4324.                JNZ     CK_I
  4325.                MOV     UNINSTALL_FLAG,1
  4326.                CALL    CK_INSTALLED            ;Else, see if installed.
  4327.                JZ      NO_TSR
  4328.                JMP     UNINSTALL               ;Else, uninstall.
  4329. NO_TSR:        MOV     DX,OFFSET NOT_INSTALLED ;If no, exit with error message.
  4330.                JMP     MSG_EXIT
  4331.  
  4332. CK_I:          CMP     AL,"I"                  ;Is it (I)nstall?
  4333.                JNZ     CK_G
  4334.                MOV     INSTALL_FLAG,1
  4335.                JMP     NEXT_SWITCH
  4336.  
  4337. CK_G:          CMP     AL,"G"                  ;Is it (G)raphic chars?
  4338.                JNZ     CK_P
  4339.                MOV     ES:IBM_FLAG,1
  4340.                JMP     NEXT_SWITCH
  4341.  
  4342. CK_P:          CMP     AL,"P"                  ;Is it (P)rinter setup codes?
  4343.                JNZ     CK_H
  4344.                CALL    GET_SETUP
  4345.                JMP     NEXT_SWITCH
  4346.  
  4347. CK_H:          CMP     AL,"H"                  ;Is it (H)otkey?
  4348.                JNZ     CK_C
  4349.                CALL    CHANGE_HOT
  4350.                JMP     NEXT_SWITCH
  4351.  
  4352. CK_C:          CMP     AL,"C"                  ;Is it (C)hime OFF?
  4353.                JNZ     CK_A
  4354.                CALL    GET_ON_OFF
  4355.                MOV     ES:NOBELL_FLAG,AH
  4356.                JMP     NEXT_SWITCH
  4357.  
  4358. CK_A:          CMP     AL,"A"                  ;Is it (A)ppointment popup OFF?
  4359.                JNZ     CK_M
  4360.                CALL    GET_ON_OFF
  4361.                MOV     ES:NOPOPUP_FLAG,AH
  4362.                JMP     NEXT_SWITCH
  4363.  
  4364. CK_M:          CMP     AL,"M"                  ;Is it (M)idnight rollover OFF?
  4365.                JNZ     CK_B
  4366.                CALL    GET_ON_OFF
  4367.                MOV     ES:NOMIDNIGHT_FLAG,AH
  4368.                JMP     NEXT_SWITCH
  4369.  
  4370. CK_B:          CMP     AL,"B"                  ;Is it (B)lack and white switch
  4371.                JZ      GOT_B
  4372.                JMP     TERMINATE
  4373. GOT_B:         MOV     ES:MONO_FLAG,1
  4374.                JMP     NEXT_SWITCH
  4375.  
  4376. ;----------------------------------------------;
  4377. INSTALL:       CALL    CK_INSTALLED            ;Check if already installed.
  4378.                JZ      CK_AVAILABLE            ;If no, see if enough memory.
  4379.                CALL    ANNOUNCE
  4380.                MOV     DX,OFFSET ALREADY_MSG   ;If yes, display "Already
  4381.                CALL    PRINT_STRING            ; installed" and
  4382.                CALL    DISP_HOTKEY             ; current hotkey.
  4383.                XOR     AL,AL                   ; EL = 0
  4384.                JMP     TERMINATE
  4385.  
  4386. ;----------------------------------------------;
  4387. CK_AVAILABLE:  MOV     BX,OFFSET RESIDENT_END
  4388.                ADD     BX,15                   ;Round up.
  4389.                MOV     CL,4
  4390.                SHR     BX,CL                   ;Convert to paragraphs.
  4391.                MOV     AH,4AH
  4392.                INT     21H                     ;Allocate memory.
  4393.                JNC     GET_VERSION
  4394.                MOV     DX,OFFSET NOT_ENOUGH    ;Exit if not enough
  4395.                JMP     MSG_EXIT                ; with message.
  4396.  
  4397. GET_VERSION:   MOV     AH,30H                  ;Get DOS version
  4398.                INT     21H
  4399.                XCHG    AL,AH
  4400.                MOV     DOS_VERSION,AX          ; and save.
  4401.                CMP     AH,2
  4402.                JAE     GET_PATH
  4403.                MOV     DX,OFFSET WRONG_VERSION ;If not DOS 2 or above, exit.
  4404.                JMP     MSG_EXIT
  4405.  
  4406. GET_PATH:      MOV     DX,OFFSET TSR           ;Open .COM file.
  4407.                MOV     AX,3D00H
  4408.                INT     21H
  4409.                JNC     FOUND_PATH
  4410. NOT_FOUND:     MOV     DX,OFFSET CANT_FIND     ;If can't find, exit
  4411.                JMP     MSG_EXIT                ; with message.
  4412.  
  4413. FOUND_PATH:    MOV     BX,AX                   ;Close .COM file.
  4414.                MOV     AH,3EH
  4415.                INT     21H
  4416.  
  4417.                MOV     AH,19H                  ;Get default drive.
  4418.                INT     21H
  4419.                ADD     AL,"A"
  4420.                MOV     DI,OFFSET PATH
  4421.                STOSB
  4422.                MOV     AL,":"                  ;Add delimiters.
  4423.                STOSB
  4424.                MOV     AL,"\"
  4425.                STOSB
  4426.                MOV     SI,DI
  4427.                XOR     DL,DL
  4428.                MOV     AH,47H                  ;Get default directory.
  4429.                INT     21H
  4430.                JC      NOT_FOUND
  4431.  
  4432. FIND_END:      LODSB                           ;Find end of path.
  4433.                OR      AL,AL
  4434.                JNZ     FIND_END
  4435.                MOV     DI,SI
  4436.                DEC     DI
  4437.                MOV     AL,"\"                  ;Add on delimiter if root.
  4438.                CMP     [DI-1],AL
  4439.                JZ      STORE_PATH
  4440.                STOSB
  4441. STORE_PATH:    MOV     PATH_END,DI
  4442.  
  4443. GET_INDOS:     MOV     AH,34H                  ;Undocumented INDOS call.
  4444.                INT     21H
  4445.                MOV     DOS_SEGMENT,ES
  4446.                MOV     INDOS_OFFSET,BX
  4447.  
  4448.                MOV     AX,3E80H                ;CMP opcode
  4449.                MOV     CX,2000H                ;Max search length
  4450.                MOV     DI,BX                   ;Look for Critical error address.
  4451. INIT4:         REPNZ   SCASW
  4452.                JCXZ    INIT5
  4453.                CMP     BYTE PTR ES:[DI+5],0BCH
  4454.                JZ      FOUND
  4455.                JMP     INIT4
  4456. INIT5:         MOV     CX,2000H
  4457.                INC     BX                      ;Odd addresses.
  4458.                MOV     DI,BX
  4459. INIT6:         REPNZ   SCASW
  4460.                JCXZ    NOTFOUND
  4461.                CMP     BYTE PTR ES:[DI+5],0BCH
  4462.                JZ      FOUND
  4463.                JMP     INIT6
  4464.  
  4465. NOTFOUND:      MOV     DX,OFFSET CRITICAL_MSG
  4466.                JMP     MSG_EXIT
  4467.  
  4468. FOUND:         MOV     AX,ES:[DI]
  4469.                MOV     ERRFLAG_OFFSET,AX
  4470.  
  4471.                CMP     INSTALL_FLAG,1          ;Install request?
  4472.                JZ      CK_SIDEKICK
  4473.                MOV     AH,0FH                  ;If no, change to text
  4474.                INT     10H                     ; video mode if necessary.
  4475.                CMP     AL,2
  4476.                JZ      GET_VECTORS
  4477.                CMP     AL,7
  4478.                JZ      GET_VECTORS
  4479.                CMP     AL,3
  4480.                JZ      GET_VECTORS
  4481.                MOV     AX,3
  4482.                INT     10H
  4483.                JMP     SHORT GET_VECTORS
  4484.  
  4485. CK_SIDEKICK:   XOR     AX,AX                   ;Check if SideKick installed.
  4486.                MOV     ES,AX
  4487.                MOV     ES,ES:[(9 * 4) + 2]     ;INT 9 segment
  4488.                CMP     WORD PTR ES:[16CH],"KS" ;SideKick signature.
  4489.                JNZ     GET_VECTORS
  4490.                MOV     DX,OFFSET SIDEKICK_MSG
  4491.                JMP     MSG_EXIT
  4492.  
  4493. GET_VECTORS:   PUSH    CS
  4494.                POP     ES
  4495.                CALL    UPDATE_DATE             ;Update calendar variables.
  4496.                MOV     YEAR_CAL,CX
  4497.                MOV     DAY_MON_CAL,DX
  4498.                CALL    GET_BIOS_DATA           ;Get BIOS variables.
  4499.                MOV     SI,OFFSET SCH_DAT
  4500.                CALL    APPEND
  4501.                CALL    CK_DATE
  4502.  
  4503.                MOV     AX,3508H                ;INT 8
  4504.                INT     21H
  4505.                MOV     OLD8[0],BX
  4506.                MOV     OLD8[2],ES
  4507.                MOV     DX,OFFSET TIMER         ;Install new interrupt.
  4508.                MOV     AX,2508H
  4509.                INT     21H
  4510.  
  4511.                MOV     AX,3510H                ;Get INT 10 interrupt.
  4512.                INT     21H
  4513.                MOV     OLD10[0],BX             ;Save old interrupt.
  4514.                MOV     OLD10[2],ES
  4515.                MOV     DX,OFFSET VIDEO         ;Install new interrupt.
  4516.                MOV     AX,2510H
  4517.                INT     21H
  4518.  
  4519.                MOV     AX,3513H                ;Get INT 13 vector.
  4520.                INT     21H
  4521.                MOV     OLD13[0],BX             ;Save old interrupt.
  4522.                MOV     OLD13[2],ES
  4523.                MOV     DX,OFFSET BDISK         ;Install new interrupt.
  4524.                MOV     AX,2513H
  4525.                INT     21H
  4526.  
  4527.                MOV     AX,3528H                ;Get INT 28 interrupt.
  4528.                INT     21H
  4529.                MOV     OLD28[0],BX             ;Save old interrupt.
  4530.                MOV     OLD28[2],ES
  4531.                MOV     DX,OFFSET BACKPROC      ;Install new interrupt.
  4532.                MOV     AX,2528H
  4533.                INT     21H
  4534.  
  4535.                CMP     INSTALL_FLAG,1          ;Install request?
  4536.                JZ      INSTALL_INT9            ;If no, skip INT 9
  4537.                CALL    MAIN                    ; and just popup now.
  4538.                JMP     SHORT UNINSTALL         ;Uninstall vectors on return.
  4539.  
  4540. STAY_RESIDENT: CALL    PRINT_STRING
  4541. INSTALL_INT9:  MOV     AX,3509H                ;Get INT 9 vector.
  4542.                INT     21H
  4543.                MOV     OLD9[0],BX              ;Save old interrupt.
  4544.                MOV     OLD9[2],ES
  4545.                MOV     DX,OFFSET KEYBOARD      ;Install new interrupt.
  4546.                MOV     AX,2509H
  4547.                INT     21H
  4548.  
  4549.                MOV     AX,DS:[2CH]             ;Get environment segment.
  4550.                MOV     ES,AX
  4551.                MOV     AH,49H                  ;Free up environment.
  4552.                INT     21H
  4553.  
  4554.                CALL    ANNOUNCE
  4555.                MOV     DX,OFFSET INSTALL_MSG   ;Display install message.
  4556.                CALL    PRINT_STRING
  4557.                CALL    DISP_HOTKEY
  4558.  
  4559.                MOV     DX,OFFSET RESIDENT_END
  4560.                ADD     DX,15                   ;Round up.
  4561.                MOV     CL,4
  4562.                SHR     DX,CL                   ;Convert to paragraphs.
  4563.                MOV     AX,3100H                ;Return error code of zero.
  4564.                INT     21H                     ;Terminate but stay resident.
  4565.  
  4566. ;-------------------------------------------------------------------;
  4567. ; Exit.  Return ERRORLEVEL code 0 if successful, 1 if unsuccessful. ;
  4568. ;-------------------------------------------------------------------;
  4569. MSG_EXIT:      PUSH    DX
  4570.                CALL    ANNOUNCE
  4571.                POP     DX
  4572.                CALL    PRINT_STRING
  4573. ERROR_EXIT:    MOV     AL,1                    ;ERRORLEVEL = 1.
  4574.  
  4575. TERMINATE:     MOV     AH,4CH                  ;Terminate.
  4576.                INT     21H
  4577.  
  4578. ;---------------------------------------------------;
  4579. ; This subroutine uninstalls the resident TSR.      ;
  4580. ;---------------------------------------------------;
  4581. UNINSTALL:     MOV     CX,ES                   ;Save segment in CX.
  4582. DO_VECTORS:    MOV     AX,3508H                ;Get interrupt 8h.
  4583.                INT     21H
  4584.                CMP     BX,OFFSET TIMER         ;Has it been hooked by another?
  4585.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  4586.                MOV     BX,ES
  4587.                CMP     BX,CX                   ;Is the segment vector same?
  4588.                JNZ     UNINSTALL_ERR           ;If no, exit with error message.
  4589.  
  4590.                MOV     AX,3510H                ;Get interrupt 10h.
  4591.                INT     21H
  4592.                CMP     BX,OFFSET VIDEO         ;Has it been hooked by another?
  4593.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  4594.                MOV     BX,ES
  4595.                CMP     BX,CX                   ;Is the segment vector same?
  4596.                JNZ     UNINSTALL_ERR           ;If no, exit with error message.
  4597.  
  4598.                MOV     AX,3513H                ;Get interrupt 13h.
  4599.                INT     21H
  4600.                CMP     BX,OFFSET BDISK         ;Has it been hooked by another?
  4601.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  4602.                MOV     BX,ES
  4603.                CMP     BX,CX                   ;Is the segment vector same?
  4604.                JNZ     UNINSTALL_ERR           ;If no, exit with error message.
  4605.  
  4606.                MOV     AX,3528H                ;Get interrupt 28h.
  4607.                INT     21H
  4608.                CMP     BX,OFFSET BACKPROC      ;Has it been hooked by another?
  4609.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  4610.                MOV     BX,ES
  4611.                CMP     BX,CX                   ;Is the segment vector same?
  4612.                JNZ     UNINSTALL_ERR
  4613.  
  4614.                CMP     UNINSTALL_FLAG,1        ;Uninstall request?
  4615.                JNZ     DO_UNINSTALL            ;If no, skip INT 9.
  4616.  
  4617.                MOV     AX,3509H                ;Get interrupt 9h.
  4618.                INT     21H
  4619.                CMP     BX,OFFSET KEYBOARD      ;Has it been hooked by another?
  4620.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  4621.                MOV     BX,ES
  4622.                CMP     BX,CX                   ;Is the segment vector same?
  4623.                JZ      DEALLOCATE              ;If no, exit with error message.
  4624.  
  4625. UNINSTALL_ERR: MOV     DX,OFFSET UNLOAD_MSG    ;And exit with error message.
  4626.                CMP     UNINSTALL_FLAG,1        ;Uninstall request?
  4627.                JZ      LILLY_ERR               ;If yes, just exit.
  4628.                JMP     STAY_RESIDENT           ;Else, go resident.
  4629. LILLY_ERR:     JMP     MSG_EXIT
  4630.  
  4631. DEALLOCATE:    MOV     AH,49H                  ;Return memory to system pool.
  4632.                INT     21H
  4633.                MOV     DX,OFFSET ALLOCATE_MSG
  4634.                JC      LILLY_ERR               ;Display message if problem.
  4635.  
  4636.                MOV     DX,ES:OLD9[0]           ;Restore old INT 9.
  4637.                MOV     DS,ES:OLD9[2]
  4638.                MOV     AX,2509H
  4639.                INT     21H
  4640.  
  4641. DO_UNINSTALL:  MOV     DX,ES:OLD8[0]           ;Restore old INT 8.
  4642.                MOV     DS,ES:OLD8[2]
  4643.                MOV     AX,2508H
  4644.                INT     21H
  4645.  
  4646.                MOV     DX,ES:OLD10[0]          ;Restore old INT 10.
  4647.                MOV     DS,ES:OLD10[2]
  4648.                MOV     AX,2510H
  4649.                INT     21H
  4650.  
  4651.                MOV     DX,ES:OLD13[0]           ;Restore old INT 13.
  4652.                MOV     DS,ES:OLD13[2]
  4653.                MOV     AX,2513H
  4654.                INT     21H
  4655.  
  4656.                MOV     DX,ES:OLD28[0]          ;Restore old INT 28.
  4657.                MOV     DS,ES:OLD28[2]
  4658.                MOV     AX,2528H
  4659.                INT     21H
  4660.  
  4661.                PUSH    CS
  4662.                POP     DS                      ;Point to our data.
  4663.                CALL    ANNOUNCE
  4664.                CMP     UNINSTALL_FLAG,1
  4665.                JNZ     UNINSTALL_END
  4666.                MOV     DX,OFFSET UNINSTALL_MSG ;Display uninstall message.
  4667.                CALL    PRINT_STRING
  4668. UNINSTALL_END: XOR     AL,AL                   ;Exit with ERRORLEVEL = 0.
  4669.                JMP     TERMINATE
  4670.  
  4671. INITIALIZE     ENDP
  4672.  
  4673. ;-------------------------------------------------------;
  4674. ; OUTPUT: ZR = 1 if not installed; ZR = 0 if installed. ;
  4675. ;-------------------------------------------------------;
  4676. CK_INSTALLED:  MOV     AX,ES
  4677.                MOV     BX,CS
  4678.                CMP     AX,BX                   ;Compare segments.
  4679.                RET
  4680.  
  4681. ;----------------------------------------------;
  4682. CHANGE_HOT:    MOV     BP,ES                   ;Save segment.
  4683.                MOV     DX,CS
  4684.                CALL    FIND_START              ;Find start of parameter.
  4685.                CMP     AL,CR
  4686.                JZ      HOT_END
  4687.                MOV     BX,SI
  4688.                MOV     ES,DX
  4689.                MOV     DI,OFFSET ALT_CAPS      ;Is it "ALT"?
  4690.                MOV     CX,3
  4691.                REP     CMPSB
  4692.                JNZ     CK_CTRL
  4693.  
  4694.                MOV     ES,BP
  4695.                MOV     ES:HOT_SHIFT_KEY,ALT_STATE
  4696.                JMP     SHORT GET_HOT
  4697.  
  4698. CK_CTRL:       MOV     SI,BX
  4699.                MOV     DI,OFFSET CTRL_CAPS     ;Is it "CTRL"?
  4700.                MOV     CX,4
  4701.                REP     CMPSB
  4702.                JZ      GOT_CTRL
  4703.                MOV     SI,BX
  4704.                JMP     SHORT GET_HOT
  4705. GOT_CTRL:      MOV     ES,BP
  4706.                MOV     ES:HOT_SHIFT_KEY,CTRL_STATE
  4707.  
  4708. GET_HOT:       CALL    FIND_START              ;Find parameter start.
  4709.                CMP     AL,CR
  4710.                JZ      HOT_END
  4711.                LODSB
  4712.                MOV     CX,SCAN_COUNT
  4713.                MOV     ES,DX
  4714.                MOV     DI,OFFSET SCAN_CODES
  4715. NEXT_HOT:      SCASB                           ;Look up hotkey.
  4716.                JZ      FOUND_HOT
  4717.                INC     DI
  4718.                LOOP    NEXT_HOT
  4719.                JMP     SHORT HOT_END
  4720.  
  4721. FOUND_HOT:     MOV     AH,[DI]
  4722.                MOV     ES,BP
  4723.                MOV     ES:COMBO,AL             ;Store hotkey ASCII
  4724.                MOV     ES:HOT_KEY_SCAN,AH      ; and scan code.
  4725. HOT_END:       MOV     ES,BP
  4726.                RET
  4727.  
  4728. ;----------------------------------------------;
  4729. FIND_START:    LODSB
  4730.                CMP     AL,CR
  4731.                JZ      START_END
  4732.                CMP     AL,SPACE
  4733.                JBE     FIND_START
  4734. START_END:     DEC     SI
  4735.                RET
  4736.  
  4737. ;----------------------------------------------;
  4738. GET_SETUP:     MOV     DI,OFFSET SETUP_CODES   ;Printer setup code storage.
  4739.                MOV     BP,10                   ;Ten codes maximum.
  4740. NEXT_SETUP2:   CALL    FIND_START              ;Find parameter.
  4741.                CMP     AL,CR
  4742.                JZ      SETUP_END
  4743.                CMP     AL,"/"
  4744.                JZ      SETUP_END
  4745.                XOR     BL,BL
  4746.                MOV     CL,10
  4747. NEXT_DECIMAL:  LODSB                           ;Get a character.
  4748.                CMP     AL,"/"
  4749.                JZ      STORE_SETUP
  4750.                CMP     AL,SPACE
  4751.                JBE     STORE_SETUP
  4752.                SUB     AL,"0"                  ;ASCII to binary.
  4753.                JC      SETUP_END               ;If not between 0 and 9, skip.
  4754.                CMP     AL,9
  4755.                JA      SETUP_END
  4756.                XCHG    AL,BL                   ;Swap old and new number.
  4757.                MUL     CL                      ; last entry by ten.
  4758.                ADD     BL,AL                   ;Add new number and store in BX.
  4759.                JMP     NEXT_DECIMAL
  4760.  
  4761. STORE_SETUP:   MOV     AL,BL
  4762.                STOSB                           ;Store printer code.
  4763.                DEC     SI
  4764.                DEC     BP
  4765.                JNZ     NEXT_SETUP2
  4766.  
  4767. SETUP_END:     XOR     AL,AL                   ;NULL terminate.
  4768.                STOSB
  4769.                RET
  4770.  
  4771. ;----------------------------------------------;
  4772. DISP_HOTKEY:   PUSH    DS
  4773.                MOV     DX,OFFSET HOTKEY_MSG    ;Display hotkey message.
  4774.                CALL    PRINT_STRING
  4775.                MOV     DS,TSR_SEGMENT
  4776.                MOV     BL,COMBO
  4777.                MOV     DX,OFFSET ALT
  4778.                CMP     HOT_SHIFT_KEY,ALT_STATE
  4779.                JZ      DISP_STATE
  4780.                MOV     DX,OFFSET CTRL
  4781. DISP_STATE:    POP     DS
  4782.                CALL    PRINT_STRING            ;And current hotkey.
  4783.                MOV     DL,BL
  4784.                MOV     AH,2
  4785.                INT     21H
  4786.                MOV     DX,OFFSET HOTKEY_MSG2
  4787.                CALL    PRINT_STRING
  4788.                RET
  4789.  
  4790. ;----------------------------------------------;
  4791. ANNOUNCE:      MOV     DX,OFFSET SIGNATURE + 1 ;Display our signature.
  4792.                CALL    PRINT_STRING
  4793.                MOV     DX,OFFSET SYNTAX        ;And syntax.
  4794.                CALL    PRINT_STRING
  4795.                RET
  4796.  
  4797. ;----------------------------------------------;
  4798. ; INPUT: SI-> Next command line param.
  4799. ; OUTPUT: AH=1 if OFF; AH=0 if ON; Default=OFF.
  4800.  
  4801. GET_ON_OFF:    MOV     AH,1
  4802.                LODSB
  4803.                CMP     AL,SPACE
  4804.                JZ      GET_ON_OFF
  4805.                CMP     AL,CR
  4806.                JZ      ON_OFF_DONE
  4807.                CMP     AL,"O"
  4808.                JNZ     ON_OFF_DONE
  4809.                LODSB
  4810.                CMP     AL,"N"
  4811.                JZ      GOT_ON
  4812.                CMP     AL,"F"
  4813.                JNZ     GOT_OFF
  4814.                LODSB
  4815.                CMP     AL,"F"
  4816.                JZ      GOT_OFF
  4817.                JMP     SHORT ON_OFF_DONE
  4818.  
  4819. GOT_ON:        DEC     AH
  4820. GOT_OFF:       INC     SI
  4821.  
  4822. ON_OFF_DONE:   DEC     SI
  4823.                RET
  4824.  
  4825. ;----------------------------------------------;
  4826. PRINT_CHAR:    MOV     DL,AL
  4827.                MOV     AH,2                    ;Print character via DOS.
  4828.                JMP     SHORT DOS_INT
  4829.  
  4830. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  4831. DOS_INT:       INT     21H
  4832.                RET
  4833.  
  4834. _TEXT          ENDS
  4835.                END     START
  4836.